默认移动成员定义为已删除,而未定义特殊成员?
Defaulted move members defined as deleted, when no special members defined?
在Accu 2014的一次演讲中,有一张幻灯片基本上是这样写的:
如果用户声明没有特殊成员函数(构造函数/析构函数/operator=
(,则"默认移动成员定义为已删除"。幻灯片 21,此处。
然而,这个简单的程序将打印移动函数被调用:
#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
没有任何特殊功能,但似乎调用了移动函数,这违反了幻灯片中的规则,因为应该删除移动函数。
幻灯片错了吗?我误解了什么吗?关于此的标准是否发生了变化(我尝试使用-std=c++11/14/17
编译,相同的结果(?
你误读了幻灯片。我将在此处复制该幻灯片的全文:
- 如果默认的特殊成员必须执行非法操作,例如调用另一个已删除的函数,则"默认"可能表示"已删除"。
- 定义为已删除的默认移动成员实际上表现为未声明。
- 不,我不是在开玩笑!
它的意思是:"如果默认的特殊成员必须做一些非法的事情,它被定义为删除。如果默认移动成员定义为已删除,则它实际上的行为就像根本没有声明一样。
您的解释错过了粗体如果。这并不是说移动默认移动成员将始终被删除。它的意思是,如果删除默认的移动成员,则认为它根本没有声明(C++11(或不参与重载解析(C++14+(,这实际上与不存在相同。换句话说,这样的类在移动时将静默地回退到执行复制。
相关文章:
- 将成员函数保留为未定义
- 使用多个源文件时对类成员函数的未定义引用
- 对专用模板成员的未定义引用
- 访问从联合与另一个成员集复制的联合中的一个成员是否未定义或未指定?
- 默认移动成员定义为已删除,而未定义特殊成员?
- 对类的静态成员的未定义引用
- 我正在尝试在我的类中创建一个静态成员,但编译器警告我它是未定义的
- C++:私有类指针成员返回未定义的值
- 未定义的行为错误:对成员变量的更改仅在某些上下文中可见
- 标头中的成员变量未定义
- 大小未定义为类成员的向量
- 如何解决对自己的C++成员函数的未定义引用?
- 对成员函数和变量的未定义引用
- C++对已继承的受保护类成员的未定义引用
- 从其后声明的另一个成员数据初始化成员数据是否为未定义行为
- 成员初始值设定项列表中的递增是否会生成未定义的行为?
- 对静态 constexpr 成员的未定义引用仅由值使用
- 静态 constexpr 模板成员在专用时提供未定义的引用
- 对完整模板专业类成员功能的未定义引用,但不是部分专业化
- 类c++中的静态成员未定义引用