Mat*_*u G 3 c++ templates clang++
这无法用 clang++ 编译,有人可以解释为什么吗?(这用 g++ 编译得很好)
struct X
{
template <typename T> X() {}
};
template X::X<int>();
int main() { return 1; }
instantiate.cc:7:13: error: qualified reference to 'X' is a constructor name rather than a type in this context
template X::X<int>();
^
instantiate.cc:7:14: error: expected unqualified-id
template X::X<int>();
^
2 errors generated.
Run Code Online (Sandbox Code Playgroud)
构造函数没有名字。正如[class.ctor]/1 中所说的那样。它们是使用类名定义的特殊成员。但他们自己是无名的。虽然 C++ 允许我们通过使用类名在某些上下文中引用 c'tor,但这些是有限的。通常,我们不能命名 c'tor。
这就是问题所在。要明确指定模板参数,我们必须使用模板化实体的名称。构造函数没有名称,因此我们无法明确指定它们的参数。
这是 [temp.arg.explicit] 中一个注释的主题,它总结了规范文本的意图。
7 [?注:因为显式模板实参列表跟在函数模板名之后,并且因为转换成员函数模板和构造函数成员函数模板是在不使用函数名的情况下调用的,所以没有办法为这些函数提供显式模板实参列表模板。?—?尾注?]
我们仍然可以实例化或特化构造函数,但前提是不必显式指定模板参数(如果它们是可推导的,或者来自默认模板参数)。例如
struct X
{
template <typename T> X(T) {}
};
template X::X(int); // This will work
Run Code Online (Sandbox Code Playgroud)
所以 Clang 拒绝你的代码并没有错。并且 GCC 有可能提供扩展。但最终,该标准没有提供一种向构造函数模板显式提供模板参数的方法。
进一步挖掘后,有CWG581,进一步确认 Clang 的行为是预期的。它似乎也进入了最新的标准修订版,并对规范文本进行了一些更改。