【发布时间】:2022-01-09 09:21:48
【问题描述】:
为什么显式默认析构函数会禁用类中的默认移动构造函数?我知道它确实,正如几个现有答案中所解释的那样。 (例如Explicitly defaulted destructor disables default move constructor in a class)
我想知道为什么:当它实际上并没有做任何暗示移动构造函数可能需要自定义代码的事情时,这样做的理由是什么?事实上,我们建议人们使用=default 而不是空的主体,因为这样编译器就知道除了自动操作之外它不会做任何事情,就像它是在没有任何声明的情况下自动生成的一样。
真的很清楚,我知道为什么用你自己的逻辑定义析构函数应该抑制自动生成。我指出=default 与让编译器隐式生成它相比并没有改变任何东西,所以这个原因在这里不适用。
我记得 >10 年前有很多关于什么是指定它的正确方法的讨论。我不记得,如果我知道的话,为什么它最终会变成这样。有没有人知道为什么这本身就是一个特定的理想功能的令人信服的原因,或者为什么它应该是这样的一些技术原因?
演示:https://gcc.godbolt.org/z/86WGMs7bq
#include <type_traits>
#include <utility>
#include <string>
#include <iostream>
struct C
{
std::string s;
C () : s{"default ctor"} {}
// ~C() = default; // <<< comment this line out, and we see that original.s has its contents "stolen"
// <<< with this dtor declared, the original string is copied.
};
int main()
{
C original;
original.s = "value changed";
C other { std::move(original) };
using std::cout;
cout << "original now: " << original.s << '\n';
cout << "other is: " << other.s << '\n';
}
这条规则在cppreference中有说明,前几天在刚刚发布的一个C++会议视频中提到过,这让我想起了它。
【问题讨论】:
-
你能提供代码来证明这一点吗?因为I have code saying otherwise.
-
@JDługosz 问题在于您将析构函数设为私有。如果您将访问权限更改为公共,则该类将是可移动构造的。
-
std::is_move_constructible不是检查这个的正确方法。来自cppreference:“类型没有移动构造函数,但具有接受 const T& 参数的复制构造函数,满足 std::is_move_constructible。” -
这可能是一个更好的例子:godbolt.org/z/n6P13z3j3 从程序集中你可以看到它调用了
CanMove::CanMove(CanMove&&)和CannotMove::CannotMove(CannotMove const&) -
@JDługosz 这个有用吗?我猜你不是第一个问这个问题的人:stackoverflow.com/a/50490555/4885321
标签: c++ language-lawyer move-semantics move-constructor