【问题标题】:C++14 warning: too many template headers for variable (should be 0)C++14 警告:变量的模板头太多(应为 0)
【发布时间】:2015-07-15 02:42:50
【问题描述】:

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

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

结果:

警告:a 的模板标头过多(应为 0)

同样有效的是,它并没有真正专门化a&lt;int&gt;。例如

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?
}

这个语法有什么奥秘?

【问题讨论】:

  • 这是一个非常具有误导性的警告。我很惊讶这不是一个错误。这是唯一的诊断吗?
  • @Yakk,在 g++-5 中是的,这是唯一的诊断。不过,不确定 clang。
  • 啊,我想我现在收到警告了!这是说int a = 1; 应该有0 个模板头,其中template&lt; 不管&gt; 是一个模板头。想象一下,如果你在它之前删除了template&lt;class T&gt; T a;——警告是有道理的。仍然令人震惊的是,这是一个警告,而不是错误。
  • 复制自here如果你特化了[一个变量模板],那么又会导致多重定义错误。例如template&lt;typename T&gt; T a = 1; template&lt;&gt; int a = 0;,如果你把这个语句放在一个公共头文件中,那么 ... 语句将导致链接器错误.

标签: c++ language-lawyer c++14 template-specialization variable-templates


【解决方案1】:

模板参数只能在 function 模板的显式特化中被省略。你有一个变量模板,所以你必须包含&lt;int&gt;

template<> int a<int> = 1;

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

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

如果不想重复输入,可以使用auto

template<> auto a<int> = 1;

[Live example] 使用 Clang。

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

【讨论】:

  • 有趣,int 之间的写法似乎是多余的 :-)。无论如何,template&lt;&gt; auto a&lt;int&gt; = 1; 也可以!
  • 这里要小心auto。如果您希望变量与模板参数具有相同的类型(不一定与初始化程序匹配),那么您可能会感到惊讶。
  • @MikeSeymour 确实如此,我会在答案中添加一个警告。
  • 请注意,您可能有意希望变量模板具有与模板参数类型不同的类型。像template &lt;class T&gt; bool predicate&lt;T&gt; = false; template&lt;&gt; bool predicate&lt;some_concrete_type&gt; = true; 这样的用法可能更符合委员会的想法。
  • @zwol 我知道专业化可能需要不同的类型。这是因为这不是 OP 想要的,所以我添加了警告。
猜你喜欢
  • 1970-01-01
  • 2014-10-14
  • 2013-10-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多