转载:https://www.jianshu.com/p/b56d59f77d53
1.类型参数
// 类模板想象成一个编译期的函数,不同的是它的参数列表放在一对尖括号中。
// typename: 指定参数,即T是参数,template:指定模板,即Stack<T>
template<typename T> struct Stack
{
std::vector<T> elems;
}
Stack<int> intStack;
intStack.push(-1);
2.默认参数
template<typename T, typename Container = std::vector<T>> struct Stack
{
Container elems;
}
// T: int;Container: std::deque
Stack<int, std::deque<int>> intStack;
3.模板的模板参数
template<typename T,
template<typename> class Container = std::vector> struct Stack;
// Container<T> elems
// 只能是class, 不能是typename
通常是这样,但是std::deque类模板在stl库中的定义有两个类型参数,第一个参数是元素类型,
第二个参数是分配器allocator的类型。虽然std::deque的第二个类型参数有默认值
但是当编译器使用std::deque替换Container时却会严格匹配参数,默认值被忽略了。即
Stack<int, std::deque> intStack; // error
template<typename T,
template<typename Elem, typename Allocator = std::allocator<Elem>>
class Container = std::vector> struct Stack
{
// 这个时候Container已经带参数了
Container<T> elems;
}
Stack<int, std::deque> intStack; // success
3.模板的非类型参数
template<char *str> struct Stack;
// 支持整型常量(包括enum),
// 指向外部链接的指针(包括函数指针、类的成员函数指针:
extern const char str[] = "Hello";
Token<str> token;
std::cout << tocken.name << std::endl;
// 具有外部链接的字符串常量指针: const char* str = "Hello";