继承的构造函数不能用于复制对象
Inherited constructor cannot be used to copy object
此程序无法编译:
template <class T>
struct Base {
Base();
template <class U>
Base(const Base<U>&);
};
template <class T>
struct Doh : Base<T> {
using Base<T>::Base;
};
template <class T>
struct Derp : Base<T> {
using Base<T>::Base;
};
Doh<void> x = Derp<void>();
错误消息显示 inherited constructor cannot be used to copy object
。 Live demo.
但是当我们将最后一行更改为此时,它会编译。
Doh<void> doh;
Doh<void> x1 = doh;
Doh<void> x2 = Derp<void*>();
Doh<void> x3(Derp<void>());
这三种情况都可以使用继承的构造函数。为什么?
因为这就是规定的工作方式。
[over.match.funcs/9] A constructor inherited from class type C ([class.inhctor.init]) that has a first parameter of type “reference to cv1 P” (including such a constructor instantiated from a template) is excluded from the set of candidate functions when constructing an object of type cv2 D if the argument list has exactly one argument and C is reference-related to P and P is
reference-related to D.
这里D = Doh<void>
,C = Base<void>
,感兴趣的构造函数是带有U = void
的构造函数,它使P = Base<void>
。该构造函数不可用,没有其他构造函数适合。
Doh<void> x1 = doh;
这没问题,因为它使用了 Doh<void>
的默认复制构造函数。
Doh<void> x2 = Derp<void*>();
这没关系,因为 Base<void*>
与 Doh<void>
没有引用相关。
这种语言的“要点”是他们想要排除看起来像 copy/move 构造函数的东西。 Base
模板构造函数可能是贪婪的,并且比提供的或默认的 Derived
copy/move 构造函数更匹配,这可能会令人惊讶。
已更新:
Doh<void> x3(Derp<void>());
这并没有声明和初始化一个Doh<void>
。它声明了一个函数 x3
返回一个 Doh<void>
并接受一个参数,这是一个不接受参数和 returns Derp<void>
的函数。是“最头疼的解析”的典型例子。
要声明和初始化一个Doh<void>
,可以使用大括号:
Doh<void> x3{Derp<void>()};
这无法按预期编译。
此程序无法编译:
template <class T>
struct Base {
Base();
template <class U>
Base(const Base<U>&);
};
template <class T>
struct Doh : Base<T> {
using Base<T>::Base;
};
template <class T>
struct Derp : Base<T> {
using Base<T>::Base;
};
Doh<void> x = Derp<void>();
错误消息显示 inherited constructor cannot be used to copy object
。 Live demo.
但是当我们将最后一行更改为此时,它会编译。
Doh<void> doh;
Doh<void> x1 = doh;
Doh<void> x2 = Derp<void*>();
Doh<void> x3(Derp<void>());
这三种情况都可以使用继承的构造函数。为什么?
因为这就是规定的工作方式。
[over.match.funcs/9] A constructor inherited from class type C ([class.inhctor.init]) that has a first parameter of type “reference to cv1 P” (including such a constructor instantiated from a template) is excluded from the set of candidate functions when constructing an object of type cv2 D if the argument list has exactly one argument and C is reference-related to P and P is reference-related to D.
这里D = Doh<void>
,C = Base<void>
,感兴趣的构造函数是带有U = void
的构造函数,它使P = Base<void>
。该构造函数不可用,没有其他构造函数适合。
Doh<void> x1 = doh;
这没问题,因为它使用了 Doh<void>
的默认复制构造函数。
Doh<void> x2 = Derp<void*>();
这没关系,因为 Base<void*>
与 Doh<void>
没有引用相关。
这种语言的“要点”是他们想要排除看起来像 copy/move 构造函数的东西。 Base
模板构造函数可能是贪婪的,并且比提供的或默认的 Derived
copy/move 构造函数更匹配,这可能会令人惊讶。
已更新:
Doh<void> x3(Derp<void>());
这并没有声明和初始化一个Doh<void>
。它声明了一个函数 x3
返回一个 Doh<void>
并接受一个参数,这是一个不接受参数和 returns Derp<void>
的函数。是“最头疼的解析”的典型例子。
要声明和初始化一个Doh<void>
,可以使用大括号:
Doh<void> x3{Derp<void>()};
这无法按预期编译。