c++ - 继承的构造函数不能用于复制对象

标签 c++ inheritance copy-constructor

这个程序不编译:

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>();

错误消息说继承的构造函数不能用于复制对象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> 无关.

这种语言的“要点”是他们想要排除看起来像复制/移动构造函数的东西。 Base否则模板构造函数可能是贪婪的,并且比提供的或默认的 Derived 更匹配。复制/移动构造函数可能会令人惊讶。


更新:

Doh<void> x3(Derp<void>());

这不会声明和初始化 Doh<void> .它声明了一个函数 x3返回 Doh<void>并接受一个参数,这是一个不接受参数并返回 Derp<void> 的函数.是“最头疼的解析”的典型例子。

声明并初始化一个Doh<void> ,你可以使用大括号:

Doh<void> x3{Derp<void>()};

这无法按预期编译。

关于c++ - 继承的构造函数不能用于复制对象,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/66432181/

相关文章:

iphone - Objective-C 私有(private)方法困境

objective-c - 为每个子类提供自己的类变量副本

c++ - 三法则的异常(exception)?

c++ - 显式删除移动构造函数

c++ - 在全局变量上使用 placement new 时有什么不正确的地方吗?

c++ - boost::stacktrace 打印地址

c++ - stdio.h 和 iostream 之间有什么区别?

css - 如何使CSS中的内部UL列表不继承外部UL列表

c++ 11使用静态断言模板参数的行为

c++ - 按值赋值运算符不使用显式复制构造函数编译