Skip to content

Commit

Permalink
Merge pull request #6 from XuhuaHuang/Template_example
Browse files Browse the repository at this point in the history
Created  example on function and class template.
  • Loading branch information
XuhuaHuang authored Nov 27, 2022
2 parents 8484c55 + 7f1b4dd commit 82b19d6
Show file tree
Hide file tree
Showing 5 changed files with 190 additions and 0 deletions.
18 changes: 18 additions & 0 deletions Template/CMakelists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
cmake_minimum_required(VERSION 3.20)

project(Template)

set(CMAKE_CXX_STANDARD 23)
set(CMAKE_CXX_STANDARD_REQUIRED ON)

# Adding multiple executable to the project
# Right-click on each item to set as start-up project
add_executable(ClassTemplateBasics
"ClassTemplate/main.cpp"
"ClassTemplate/Stack.hpp"
)

add_executable(FunctionTemplateBasics
"FunctionTemplate/main.cpp"
"FunctionTemplate/max.hpp"
)
69 changes: 69 additions & 0 deletions Template/ClassTemplate/Stack.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
/*****************************************************************//**
* \file Stack.hpp
* \brief Basic templated Stack class implementation using std::vector
*
* \author Xuhua Huang
* \date November 15, 2022
*********************************************************************/

#ifndef STACK_HPP
#define STACK_HPP

#ifndef _IOSTREAM_
#include <iostream>
#endif

#include <cassert>
#include <vector>

template<typename T>
class Stack {
private:
std::vector<T> elems;
public:
Stack() = default;
Stack(const Stack& rhs) = default;
Stack(Stack&& rhs) : elems(std::move(rhs.elems)) {}

void push(const T& elem);
T pop();
T top() const;
bool empty() const {
return elems.empty();
}

auto operator<=>(const Stack& rhs) -> int;

/**
* implicit requriement:
* operator << must be overloaded for generic type T.
*/
void print() const {
for (const T& elem : elems) {
std::cout << elem << " ";
}
}
};

template<typename T>
void Stack<T>::push(const T& elem) {
// insert element at the end
elems.push_back(elem);
return;
}

template<typename T>
T Stack<T>::pop() {
assert(!elems.empty());
T elem = elems.back(); // copy the last element
elems.pop_back(); // remove the last element
return elem; // return the saved copy
}

template<typename T>
T Stack<T>::top() const {
// return last element
return elems.back();
}

#endif
42 changes: 42 additions & 0 deletions Template/ClassTemplate/main.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
/*****************************************************************//**
* \file main.cpp
* \brief
*
* \author Xuhua Huang
* \date November 15, 2022
*********************************************************************/

#include <iostream>
#include <complex>
#include <string>
#include "Stack.hpp"

auto main(void) -> int {
Stack<int> intStack;
intStack.push(7);

Stack<std::string> strStack;
strStack.push("hello");
strStack.push("world");
std::cout << strStack.top() << ", ";
strStack.pop();
std::cout << strStack.top() << "! ";

/**
* Your compiler may not recognize the sequential >> operator
* at the trailling template instanciation.
* This is a known issue; change to the following instead:
* Stack<std::complex<double> > cpxStack;
* \return
*/
Stack<std::complex<double>> cpxStack;

Stack<std::pair<int, double>> pairStack;
pairStack.push(std::pair<int, double>(1, 2.0));
pairStack.push({ 3, 4.00 });
std::cout << pairStack.top().first << "\n";

//pairStack.print(); // compile-time error; std::pair does not overload operator <<

return EXIT_SUCCESS;
}
22 changes: 22 additions & 0 deletions Template/FunctionTemplate/main.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
/*****************************************************************//**
* \file main.cpp
* \brief
*
* \author Xuhua Huang
* \date November 15, 2022
*********************************************************************/

#include <iostream>
#include "max.hpp"

auto main(void) -> int {
// implicit template instanciation
// T is deducted to int
// same for std::vector
// std::vector v { 1, 2 };
// std::cout << max<int>(42, 77) << "\n";
std::cout << max(42, 77) << "\n";
std::cout << max<double>(3.14, 3.1415) << "\n";

return EXIT_SUCCESS;
}
39 changes: 39 additions & 0 deletions Template/FunctionTemplate/max.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
/*****************************************************************//**
* \file main.hpp
* \brief Usually the definition of a templated function is provided
* in the same header file, instead of a separate translation unit.
*
* \author Xuhua Huang
* \date November 15, 2022
*********************************************************************/

#ifndef MAX_HPP
#define MAX_HPP

#ifndef _IOSTREAM_
#include <iostream>
#endif

#include <concepts>

/**
* This function definition has 2 implicit requirements of genric type T:
* 1. it has the comparison operator overloaded
* 2. it is copiable, since we are passing and returning by value
*/
// template<typename T>
// T max(T a, T b) {
// return b < a ? a : b;
// }

template<typename T>
concept SupportsLessThan = requires (T t) { t < t; };

/* Adding explicit constraint for T */
template<typename T>
requires std::copyable<T> && SupportsLessThan<T>
T max(T a, T b) {
return b < a ? a : b;
}

#endif

0 comments on commit 82b19d6

Please sign in to comment.