gpt4 book ai didi

c++ - 是什么导致移动构造函数被删除

转载 作者:行者123 更新时间:2023-11-27 23:56:57 24 4
gpt4 key购买 nike

我有以下示例:

#include <vector>

class noncopyable {
protected:
noncopyable() {}
~noncopyable() {}
noncopyable(const noncopyable&) = delete;
noncopyable& operator=(const noncopyable&) = delete;
noncopyable(noncopyable&&) = default;
noncopyable& operator=(noncopyable&&) = default;
};

class C1 : private noncopyable {
public:
C1() { }
~C1() { }
};

int main() {
std::vector<C1> v;
v.emplace_back();
return 0;
}

我认为它应该可以工作,因为 C1 应该是可移动的,因为它是基类并且没有数据成员。相反,我得到了一个错误(使用 clang++):

error: call to implicitly-deleted copy constructor of 'C1'
{ ::new(static_cast<void*>(__p)) _T1(std::forward<_Args>(__args)...); }
^ ~~~~~~~~~~~~~~~~~~~~~~~~~~~
.
.
.
note: in instantiation of function template specialization 'std::vector<C1, std::allocator<C1> >::emplace_back<>' requested here
v.emplace_back();
^
note: copy constructor of 'C1' is implicitly deleted because base class 'noncopyable' has a deleted copy constructor
class C1 : private noncopyable {
^
note: 'noncopyable' has been explicitly marked deleted here
noncopyable(const noncopyable&) = delete;

做一点研究 ( http://en.cppreference.com/w/cpp/language/move_constructor ) 表明,如果有一个用户定义的析构函数,则不会定义隐式移动构造函数。这似乎是这里的问题,因为 C1 有一个析构函数,移动构造函数没有被定义。果然,如果我删除析构函数或将 C1(C1&&) = default; 添加到 C1 然后它就可以工作。

到目前为止一切顺利。

问题是错误消息没有提到 ~C1() 或移动构造函数。它说它正在尝试调用在基类中删除的复制构造函数。因此,我尝试将 noncopyable 中的 deleteed 函数更改为 defaulted,并且(惊喜!),这也解决了错误。

所以我的问题是,这最后一件事与错误或更正有什么关系?如果有析构函数,基类有没有拷贝构造函数有什么区别?

最佳答案

你不需要vector,一个更简单的例子就是:

C1 a;
C1 b(std::move(a)); // error: C1's copy constructor is deleted

来自[class.copy]:

If the definition of a class X does not explicitly declare a move constructor, a non-explicit one will be implicitly declared as defaulted if and only if
(9.1) — X does not have a user-declared copy constructor,
(9.2) — X does not have a user-declared copy assignment operator,
(9.3) — X does not have a user-declared move assignment operator, and
(9.4) — X does not have a user-declared destructor.

C1 有一个用户声明的析构函数,因此它没有移动构造函数。 C1 确实但是有一个隐式声明的复制构造函数

If the class definition does not explicitly declare a copy constructor, a non-explicit one is declared implicitly. If the class definition declares a move constructor or move assignment operator, the implicitly declared copy constructor is defined as deleted; otherwise, it is defined as defaulted (8.4). The latter case is deprecated if the class has a user-declared copy assignment operator or a user-declared destructor.

C1 上的完整构造函数集,显式和隐式,如下所示:

C1();
C1(C1 const& ) = default; // but also delete
~C1();

因此尝试从 C1 类型的右值构造一个 C1 将匹配隐式声明的复制构造函数作为最佳匹配(没有其他可行的),但是那个构造函数已删除,因为 noncopyable 的复制构造函数已已删除,因此整个表达式的格式不正确。

这就是错误消息提到构造函数的原因。该移动构造格式错误,因为该移动构造的最佳匹配是复制构造函数格式错误。它不能提及移动构造函数,因为没有移动构造函数,并且析构函数与手头的表达式无关。当您将基类更改为可复制时,现在 C1 也变为可复制 - 所以没有错误。仍然没有移动构造函数,只是现在有一个可行的移动构造候选者。

关于c++ - 是什么导致移动构造函数被删除,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41991363/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com