template
关键字除了用于作为模板声明之外,还有一个作用,显式说明模板成员函数,这一点类似于typename
显式说明成员类型。给出代码实例:
#include <iostream>
template<typename T, size_t N>
class Collection {
public:
template<size_t I>
void setValue(T &&t) {
data[I] = t;
}
template<size_t I>
T getValue() const {
return data[I];
}
private:
T data[N];
};
template<typename T, size_t N, size_t I>
void printElem(Collection<T, N> &con) {
// ==> 1
std::cout << con.template getValue<I>() << std::endl;
}
int main() {
// 正常版本,这里不用声明.template
Collection<double, 2> con{};
con.setValue<0>(0.1);
con.setValue<1>(1.5);
std::cout << con.getValue<0>() << std::endl;
printElem<double, 2, 1>(con);
}
在上面代码1中,如果不加.template
关键字,则会报错。这么理解,printElem
是个模板函数,传入的参数Collection
类型依赖于printElem
的模板参数。但是,1处在完成实例化填充之前,编译器不会实际赋予模板实际的类型,因此这里的.template
是用来告诉编译器,I
是类型,而不是其他的数据,因此getValue
才会被编译器认为是成员函数,而不是成员变量的。