为什么不使用我的(模板)构造函数进行此初始化?
Why isn't this initialization using my (template) 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;
}
最后一行的意思是什么?
我可以假设它是一些自动创建的ctor但不知道是哪一个。
这里有几个C++语言规则。
-
模板不能是复制构造函数。(标准规则12.8p2)
如果类
X
的非模板构造函数的第一个参数类型为X&
、常量X&
、volatile X&
或const volatile X&
,并且没有其他参数,或者所有其他参数都有默认参数,则该构造函数是复制构造函数。 -
如果没有定义复制构造函数,编译器会生成一个默认的复制构造函数(如果可能的话)。(标准规则12.8p7)
如果类定义没有显式声明复制构造函数,则隐式声明一个如果类定义声明了移动构造函数或移动赋值运算符,则隐式声明的复制构造函数被定义为已删除;否则,它被定义为默认值(8.4)。如果类具有用户声明的复制赋值运算符或用户声明的析构函数,则不赞成使用后一种情况。因此,对于类别定义
struct X { X(const X&, int); };
复制构造函数是隐式声明的。如果用户声明的构造函数后来被定义为
X::X(const X& x, int i =0) { /∗ ... ∗/ }
那么CCD_ 7的复制构造函数的任何使用都是由于歧义而形成的;不需要进行诊断。 -
如果一个模板和非模板的参数匹配得同样好,则非模板获胜。(标准规则13.3.3)该规则是一个难以消化的大混乱,我只展示重要部分:
[…]如果[…rules about argument matching…],则可行函数
F1
被定义为比另一个可行函数F2
更好的函数,或者,如果不是,则F1
是非模板函数,F2
是函数模板专用化[…]
根据您提供的代码,只有
C<int>::C(const C<int>&)
是一个用户定义的复制构造函数,用于打印2
。除了int
之外的所有X
都没有定义复制构造函数,因此编译器会创建一个。
另请参见
- 模板复制构造函数因特定的模板类型而失败以及
- 初始化忽略构造函数模板
它是编译器为您生成的复制构造函数,由于它是最匹配的,所以在最后一种情况下选择它。
在最后一种情况下,您调用默认的复制构造函数。
- 为什么std::vector和std::valarray初始化构造函数不同
- 初始化构造函数C++中结构的向量
- C++ 中常量属性的初始化构造函数错误
- 不正确的输出和变量未用Eclipse CDT初始化构造函数
- 如何使用嵌套初始化构造函数中的一维向量初始化矩阵
- 如何通过参数初始化构造函数中的数组?
- 是否有理由使用 malloc 初始化构造函数中的指针
- 如何在 c++ 中初始化构造函数中的二维数组
- 为什么初始化构造函数列表参数时会发生异常?
- 无法初始化构造函数
- 初始化构造函数的默认参数的优选方法是什么?
- 在C++17中使用空列表初始化构造函数时发生编译错误
- C++ 初始化构造函数初始化列表中的嵌套结构?
- 初始化构造函数c++中的向量
- g++ (GCC) 4.6.0 我有以下类,我正在尝试初始化构造函数的结构成员初始化列表
- 使用字符串文本初始化构造函数中的 std::array<char,x> 成员。海湾合作委员会错误?
- 初始化构造函数C++中函数的成员指针
- 在c++中初始化构造函数中的静态成员变量时出错
- memset()初始化构造函数中的对象
- 初始化构造函数C++中的成员向量