Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/148.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 模板化类构造函数的模板实例化_C++_Templates_Clang++ - Fatal编程技术网

C++ 模板化类构造函数的模板实例化

C++ 模板化类构造函数的模板实例化,c++,templates,clang++,C++,Templates,Clang++,这无法用clang++编译,有人能解释为什么吗?(使用g++可以很好地编译) struct X { 模板X(){} }; 模板X::X(); int main(){return 1;} instantiate.cc:7:13:错误:对“X”的限定引用在此上下文中是构造函数名称而不是类型 模板X::X(); ^ instantiate.cc:7:14:错误:应为非限定id 模板X::X(); ^ 产生2个错误。 我认为叮当声是正确的。即使Gcc允许,模板化构造函数也不能使用。无法推导模板参数,也无

这无法用clang++编译,有人能解释为什么吗?(使用g++可以很好地编译)

struct X
{
模板X(){}
};
模板X::X();
int main(){return 1;}
instantiate.cc:7:13:错误:对“X”的限定引用在此上下文中是构造函数名称而不是类型
模板X::X();
^
instantiate.cc:7:14:错误:应为非限定id
模板X::X();
^
产生2个错误。

我认为叮当声是正确的。即使Gcc允许,模板化构造函数也不能使用。无法推导模板参数,也无法为构造函数模板显式指定模板参数

引用构造函数模板的专门化([class.ctor]、[class.qual])时,不应指定模板参数

[注意:由于显式模板参数列表紧跟函数模板名称,并且由于构造函数模板([class.ctor])的命名没有使用函数名称([class.qual]),因此无法为这些函数模板提供显式模板参数列表。-结束注]


构造函数没有名称。正如我在书中所说的那样。它们是通过使用类的名称定义的特殊成员。但他们自己是无名的。虽然C++允许我们通过使用类名来引用某些上下文中的Ccor,但这些限制是有限的。一般来说,我们不能命名一个c'tor

这就是问题所在。要显式指定模板参数,必须使用模板化实体的名称。构造函数没有名称,因此无法显式指定其参数

这是[temp.arg.explicit]中注释的主题,该注释总结了规范性文本的意图

[ 注意:因为显式模板参数列表遵循 函数模板名称,以及因为转换成员函数 调用模板和构造函数成员函数模板时不使用 使用函数名,无法提供显式模板 这些函数模板的参数列表。 — 尾注 ]

我们仍然可以实例化或专门化构造函数,但前提是不必显式指定模板参数(如果它们是可推断的,或来自默认模板参数)

struct X
{
模板X(T){}
};
模板X::X(int);//这将起作用
因此,Clang拒绝您的代码并没有错。GCC可能提供了一个扩展。但最终,该标准没有提供一种向构造函数模板显式提供模板参数的方法



经过进一步挖掘,我们进一步确认了Clang的行为是有意的。它似乎也进入了最新的标准修订版,对规范性文本进行了一些修改。

可能值得一提的是,我们实际上可以在不使用模板的情况下提供模板构造函数的显式实例化定义参数推断,如果我们使用默认模板参数,这是一种可能在类模板的构造函数中发现一些特殊情况用法的技术,在这种情况下,我们希望利用SFINAE来控制ctor重载;基本上,使ctor模板仅使类模板参数成为相应ctor中的依赖类型(例如:,)。(当然,对于这种SFINAE构造函数重载机制,或者对于C++20,约束表达式,我们更愿意使用依赖于类模板参数的继承)@dfri-有趣的是,在分析此类问题时,默认模板参数似乎总是从我的脑海中消失。谢谢,修改了相应的段落。我自己很少在CTOR上使用它们,但可能会在用户定义的conv.函数中使用它们,特别是使用SFINAE来避免警告:conv.func…“MyType”本身永远不会被r使用当关联的模板参数
T
已经是常量时,移除所述重载。不过,我刚刚了解到,我们对约束表达式的依赖名称没有与将SFINAE应用于类模板成员时相同的限制,这使得这一点变得更为重要。
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.
struct X
{
  template <typename T> X(T) {}
};

template X::X(int); // This will work