pap*_*nik 3 c++ templates constructor
为什么输出是0003212?
#include <iostream>
using namespace std;
template<typename X> class C
{
public:
C() { cout<<"0";}
template<class T> C(const C<T>& c) { cout<<"1";}
C(const C<int>& c) { cout<<"2";}
template<class T> C(const C<T*>& c) { cout<<"3";}
};
int main(int argc, char* args[])
{
C<int> c1; // 0
C<double> c2; // 0
C<int*> c3; // 0
C<int> c4(c3); // 3
C<int> c5(c1); // 2
C<int> c6(c2); // 1
C<float> c7(c1); // 2
C<double> c8(c2); // ?
std::cin.get();
return 0;
}
Run Code Online (Sandbox Code Playgroud)
在最后一个含义行中调用了什么?
我可以假设这是一些自动创建的ctor,但无法弄清楚哪一个.
这里有几个C++语言规则.
模板不能是复制构造函数.(标准规则12.8p2)
一个非模板类的构造函数
X是一个拷贝构造函数,如果它的第一个参数是类型X&,常量X&,volatile X&或者const volatile X&,并且或者有没有其他参数,否则所有其他参数默认参数.
如果未定义复制构造函数,则编译器将生成默认构造函数(如果可能).(标准规则12.8p7)
如果类定义没有显式声明复制构造函数,则会隐式声明一个.如果类定义声明了移动构造函数或移动赋值运算符,则隐式声明的复制构造函数被定义为已删除; 否则,它被定义为默认值(8.4).如果类具有用户声明的复制赋值运算符或用户声明的析构函数,则不推荐使用后一种情况.因此,对于课程定义
Run Code Online (Sandbox Code Playgroud)struct X { X(const X&, int); };隐式声明了复制构造函数.如果后来定义了用户声明的构造函数,
X::X(const X& x, int i =0) { /? ... ?/ }那么X由于模糊性,任何对复制构造函数的使用都是错误的; 无需诊断.
如果模板和非模板对于参数同样匹配,则非模板获胜.(标准规则13.3.3)规则是一个难以消化的大混乱,我只会展示重要的部分:
[...]一个可行的函数
F1被定义为比另一个可行的函数更好的函数,F2如果[...关于参数匹配的规则...],或者,如果不是,那么,F1是一个非模板函数,并且F2是一个函数模板专门化[...]
仅从您提供的代码中获取
C<int>::C(const C<int>&)
Run Code Online (Sandbox Code Playgroud)
是一个用户定义的复制构造函数,可以打印2.所有X比其他int没有定义拷贝构造函数,所以编译器创建一个.
也可以看看