template<class T>
class MyClass {
public:
//MyClass() = default;
template<class X>
MyClass(MyClass<X>& other)
{
val = other.getVal();
}
T getVal()
{
return val;
}
private:
T val;
};
main()
{
MyClass<double> xd; //this one causing the problem
MyClass<double> xd1(xd); //this one is fine
MyClass<int> xi(xd);
}
此代码无法编译。 但如果你取消注释MyClass()= default,那么一切都很好。 据我所知,模板不会阻止编译器生成默认的ctor和复制ctor 。 实际上编译器只在尝试通过默认ctor创建对象时抱怨,而不是在复制构造(在这种情况下是编译器生成) 代码是用g ++ 5.4.0和7.1.0编译的。与
相同的行为答案 0 :(得分:7)
这不是复制构造函数:
template<class X>
MyClass(MyClass<X>& other) {
val = other.getVal();
}
这是一个构造函数,它将可变左值引用引用到许多不同于此类的类型。
这是一个复制构造函数:
MyClass(const MyClass&) {
// ...
}
您可以通过尝试将= default
放在其签名之后来测试函数是否为特殊函数。如果编译器抱怨你滥用默认函数,那么你的功能并不是特别的。
当添加除特殊构造函数之外的任何其他构造函数时,不会生成默认构造函数。该函数作为模板与非模板函数没有任何不同的效果。在这种情况下,确实需要MyClass() = default
。
来自cppreference:
如果没有为类类型(struct,class或union)提供任何类型的用户声明的构造函数,编译器将始终将默认构造函数声明为其类的内联公共成员。
相反,如果声明了用户提供的构造函数,则不会定义隐式定义的默认构造函数。
来自[class.ctor]§5
:
类X的默认构造函数是类X的构造函数,可以在没有参数的情况下调用。如果类X没有用户声明的构造函数,则没有参数的构造函数被隐式声明为默认值(8.4)。
由于您的类具有用户提供的构造函数,因此不会生成隐式声明/定义的构造函数。同样,您可以随时使用= default
强制它生成。