模板尖括号(<...>)编写时机及类模板方法实现语法咨询
嘿,我来帮你把这两个问题理清楚!
一、何时需要编写模板尖括号<...>?
模板尖括号的使用场景主要分这几种情况:
声明/定义模板本身时:不管是模板类还是模板函数,都需要在开头用
template <typename T>(或class T)来声明模板参数,这里的尖括号是必须的,用来指定模板的类型参数列表。比如:template <typename T> class Stack { // 类成员声明 };在类外定义模板类的成员函数时:这正是你第二个问题涉及的场景!因为模板类的成员函数本身也是模板函数,所以在类外定义时,必须先写
template <typename T>,并且在类名后面加上<T>,明确这个成员属于Stack<T>这个模板实例。实例化模板类/函数时:当你要创建模板类的对象,或者调用模板函数时,需要在类名/函数名后加上尖括号,指定具体的类型参数(如果编译器不能自动推导的话)。比如:
Stack<int> myStack; // 实例化一个存储int的Stack模板特化/偏特化时:针对特定类型定制模板实现时,也需要用尖括号指定特化的类型,比如:
template <> class Stack<char*> { // 针对char*的特化实现 };
二、Stack模板的push/pop实现是否正确?
你的疑问完全正确!必须写成void Stack<T>::push(const T& t),而不是void Stack::push(const T& t),pop方法同理。
为什么呢?因为Stack本身是一个模板类,不是一个具体的类类型——只有当你指定了模板参数(比如Stack<int>)之后,它才会变成一个具体的类。在类外定义成员函数时,你必须告诉编译器:这个函数属于Stack<T>这个模板的成员,而不是某个名为Stack的普通类。
Eclipse报的“Member declaration not found”错误,本质就是编译器找不到对应Stack::push的声明——因为原类声明是Stack<T>,不是不带参数的Stack,所以编译器无法匹配到对应的成员声明。
给你一个完整的正确示例:
类声明部分
template <typename T> class Stack { public: void push(const T& t); void pop(); // 其他成员... };
类外成员函数定义部分
template <typename T> void Stack<T>::push(const T& t) { // 具体实现 } template <typename T> void Stack<T>::pop() { // 具体实现 }
这样写之后,编译器就能正确识别这些成员函数属于模板类Stack<T>的一部分,错误也就会消失啦。
内容的提问来源于stack exchange,提问作者J.Roe

