c++ - 当没有定义特殊成员时,默认移动成员定义为已删除?

标签 c++

在 Accu 2014 的一次演讲中,有一张幻灯片基本上说:

如果用户没有声明特殊成员函数(构造函数/析构函数/operator=),则“默认移动成员定义为已删除”。幻灯片 21,here .

但是,这个简单的程序将打印调用了移动函数:

#include <stdio.h>
#include <utility>

struct Foo {
    Foo() { printf("Foo()\n"); }
    Foo(const Foo &) { printf("Foo(const Foo &)\n"); }
    Foo(Foo &&) { printf("Foo(Foo &&)\n"); }
    ~Foo() { printf("~Foo()\n"); }

    Foo &operator=(const Foo &) { printf("Foo::operator=(const Foo &)\n"); return *this; }
    Foo &operator=(Foo &&) { printf("Foo::operator=(Foo &&)\n"); return *this; }
};

struct Baz {
    Foo f;
};

int main() {
    Baz b;
    Baz c(std::move(b));

    b = Baz();
}

输出:

Foo()
Foo(Foo &&)
Foo()
Foo::operator=(Foo &&)
~Foo()
~Foo()
~Foo()

在程序中,Baz没有任何特殊的函数,但似乎调用了move函数,这违反了幻灯片中的规则,因为move函数应该被删除。

幻灯片有错吗?我是否误解了什么?有关于此的标准是否发生了一些变化(我尝试使用 -std=c++11/14/17 进行编译,结果相同)?

最佳答案

您误读了幻灯片。我将在此处复制该幻灯片的全部文本:

  • “defaulted” can mean “deleted” if the defaulted special member would have to do something illegal, such as call another deleted function.
  • Defaulted move members defined as deleted, actually behave as not declared.
    • No, I’m not kidding!

它的意思是:“如果默认的特殊成员必须做一些非法的事情,那么它被定义为已删除。如果默认的移动成员被定义为已删除,它实际上的行为就好像它没有被删除一样完全宣布。”

您的解释错过了粗体的if。这并不是说移动默认移动成员将始终被删除。也就是说,如果默认的移动成员被删除,则认为它根本没有声明(C++11)或不参与重载决策(C++14+),这实际上与不存在相同。换句话说,此类类在移动时将默默地回退到执行拷贝。

关于c++ - 当没有定义特殊成员时,默认移动成员定义为已删除?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58318979/

相关文章:

c++算术中的常量类型转换

C++ 测试 double 是否为#INF

c++ - 链接 : fatal error LNK1561: entry point must be defined in empty project

c++ - 如何复制(或交换)包含引用或常量成员的类型的对象?

c++ - 如何制作模板抽象类列表

c++ - 传递一个成员函数作为 C++ 标准库算法的比较运算符

c++ - 如何在编译时检测 C++ 中的 std::reference_wrapper

c++ - 任何指标都可以衡量图像的渐晕效果?

c++ - 在 Gtk+ (gtkmm) 中连接关键加速器

c++ - std::bind 需要默认构造函数