C++ 14警告:变量的模板头太多(应为0)

iam*_*ind 19 c++ template-specialization language-lawyer variable-templates c++14

在尝试使用最近的g ++ - 5编译器时,我在一个文件中写下了以下语句:

template<T> T a;
template<> int a = 1;
Run Code Online (Sandbox Code Playgroud)

结果如下:

警告:模板标题太多a(应为0)

同样有效的是,它并不专门a<int>.例如

template<typename T> T a;
template<> int a = 1;

int main ()  {
  std::cout << a<double> << "\n";  // prints 0; OK
  std::cout << a<int> << "\n";  // prints 0! why not 1?
}
Run Code Online (Sandbox Code Playgroud)

这句法的神秘之处是什么?

Rei*_*ica 23

模板参数只能在函数模板的显式特化中省略.你有一个变量模板,所以你必须包括<int>:

template<> int a<int> = 1;
Run Code Online (Sandbox Code Playgroud)

引用C++ 14(n4140),14.7.3/10(强调我的):

可以在template-id中未指定尾随模板参数,命名显式函数模板特化,前提是它可以从函数参数类型推导出来.

如果您不想重复该类型,可以使用auto:

template<> auto a<int> = 1;
Run Code Online (Sandbox Code Playgroud)

[实例]使用Clang.

有一点要牢记:使用时auto,专用变量的类型将从初始化器推断出来,而不是从模板参数中推导出来.由于专业化可以具有与主模板不同的类型,因此即使它们不同,编译器也会乐意接受它.

  • 这里要小心`auto`.如果您期望变量与模板参数具有相同的类型(它不一定与初始化器匹配),那么您可能会感到惊讶. (2认同)