背景
template关键字主要用在模版声明和定义时,但是关于.template相关的使用和说明,由于平时使用很少所以也很少见到,本文主要讲解一下.template的含义和使用。
例子
注:本例子仅仅是为了说明.template的含义,关于C++的相应写法很随意,不具有借鉴意义
定义的模版如下:
template <typename T>
class Test {
private:
T value_{};
public:
Test(T val) : value_{val} {}
template <typename U>
struct Print {
static void printx() {
std::cout << "T value: " << 0 << "\n";
}
};
template <typename V>
void Printfunc() {
std::cout << "T value: " << 0 << "\n";
}
};
template <typename Alloc>
void print() {
Alloc::template Print<int>::printx();
// Alloc::Print<int>::printx();
}
针对上述代码,写个简单测试如下
int main() {
print<Test<int>>();
return 0;
}
我的编译器以及机器环境如下
gcc version 8.3.1 20190311 (Red Hat 8.3.1-3) (GCC)
当你在C++17的环境下编译时,编译器会报如下错误
main.cc: In function ‘void print()’:
main.cc:28:19: error: expected primary-expression before ‘int’
Alloc::Print<int>::printx();
^~~
main.cc:28:19: error: expected ‘;’ before ‘int’
Alloc::Print<int>::printx();
^~~
;
main.cc: In instantiation of ‘void print() [with Alloc = Test<int>]’:
main.cc:32:22: required from here
main.cc:28:18: error: dependent-name ‘Alloc::Print’ is parsed as a non-type, but instantiation yields a type
Alloc::Print<int>::printx();
main.cc:28:18: note: say ‘typename Alloc::Print’ if a type is meant
make: *** [main] Error 1
由main.cc:28:18的error可知,针对Alloc::Print被解析成了非type,而编译器实例化为type,所以报错。
解决改种问题的方式便是.template(或者::template, ->template)
在print()函数模版中的Alloc::后加上template后便可以获得正确结果。
.template含义
有了上述例子做作准备,现在是时候解释一下.template的含义了。
.template是告诉编译器引用了某个类模版中的一个类模版或者函数模版。
譬如print()函数模版中Alloc::template Print, 便是告诉编译器Print为模版Alloc中的一个类模版。
注:由此可以参考typename的含义