这不能用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.
答案 0 :(得分:4)
构造函数没有名称。 [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
因此Clang拒绝您的代码并没有错。 GCC可能会提供扩展。但是最终,该标准没有提供向构造函数模板显式提供模板参数的方法。
进一步研究时,发现CWG581,进一步确认了Clang的行为是预期的行为。通过对标准文本进行一些更改,它似乎也进入了最新的标准修订版。
答案 1 :(得分:2)
我认为Clang是正确的。即使Gcc允许,模板构造函数也根本无法使用。无法推导出template参数,也无法为构造函数模板明确指定template参数。
在引用构造函数模板([class.ctor],[class.qual])的特殊化时,不得指定模板参数。
[注意:因为显式模板参数列表在函数模板名称之后,并且由于构造函数模板([class.ctor])的命名没有使用函数名称([class.qual]),所以无法提供这些功能模板的显式模板参数列表。 —尾注]