Clang不会编译gcc将要使用的模板专业化

时间:2018-08-10 04:38:58

标签: c++ gcc clang language-lawyer template-specialization

Gcc可以很好地进行编译,但是Clang(trunk)拒绝了以下消息:

<source>:7:8: error: class template partial specialization is not more specialized than the primary template [-Winvalid-partial-specialization]

https://godbolt.org/g/h8rsWC

template<class T, T x>
struct S{};

template<int& x>
struct S<int&, x> { };

此代码正确吗?

1 个答案:

答案 0 :(得分:9)

这仅在-std=c++17及更高版本中体现。 “更专业”的确定需要synthesizing a pair of function templates from the class templatessynthesizing unique types, values, and templates for the template parameters,最后是performing template argument deduction in both directions。如果推导在一个方向上成功而在另一方向上不成功,则模板是“更专业的”。

在这里,Clang从两个来源推论T并得到不同的结果:

  • 从明确指定的int&中推导出T := int&
  • 从非类型参数x中,按照通常的推导规则(通常不推导引用类型)推导T := int。在C ++ 17中添加了从非类型模板参数的类型推论的功能。

这使得推论在两个方向上均失败,因此部分专业化未通过“更专业化”的测试。

这看起来像是标准中的缺陷。解决方法是在未推导的上下文中将T包装在原始模板中。