提问人:Dr. Gut 提问时间:3/2/2021 最后编辑:Dr. Gut 更新时间:3/3/2021 访问量:121
继承的构造函数不能用于复制对象
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
但是当我们将最后一行更改为此时,它就会编译。
Doh<void> doh;
Doh<void> x1 = doh;
Doh<void> x2 = Derp<void*>();
Doh<void> x3(Derp<void>());
在这三种情况下,可以使用继承的构造函数。为什么?
答:
3赞
Jeff Garrett
3/2/2021
#1
因为这就是规定的工作方式。
[over.match.funcs/9] (英语)在构造 cv2 D 类型的对象时,如果参数列表只有一个参数,并且 C 与 P 相关且 P 是 与 D 相关的参考文献。
这里 ,感兴趣的构造函数是 make 的构造函数。该构造函数不可用,并且没有其他构造函数适合。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>
这种语言的“要点”是他们想要排除看起来像复制/移动构造函数的东西。否则,模板构造函数可能是贪婪的,并且比提供或默认的复制/移动构造函数更匹配,这可能会令人惊讶。Base
Derived
更新:
Doh<void> x3(Derp<void>());
这不会声明和初始化 .它声明一个函数返回 a 并接受一个参数,这是一个不接受参数并返回 的函数。这是“最令人烦恼的解析”的典型例子。Doh<void>
x3
Doh<void>
Derp<void>
要声明和初始化 ,可以使用大括号:Doh<void>
Doh<void> x3{Derp<void>()};
这无法按预期编译。
评论
Doh<void>
Doh
Derk
Doh<void> x = Doh<void>(Derk<void>());
template <class U> Base(const Base<U>&)
Base(const Base<T>&)