在 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/