C++中.template含义
背景
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<int>, 便是告诉编译器Print<int>为模版Alloc中的一个类模版。</int></int>
注:由此可以参考typename的含义