Bau*_*gen 28 c++ language-lawyer
这个班是这样的:
class A {
public:
A() = default;
A(const A&) = delete;
};
Run Code Online (Sandbox Code Playgroud)
平凡的可复制?(至少clang似乎这么认为(现场))
会特别的
A a,b;
std::memcpy(&a, &b, sizeof(A));
Run Code Online (Sandbox Code Playgroud)
调用未定义的行为?
上下文:这个答案 [删除,因为证明错误]加上其评论树.
T.C*_*.C. 28
更新:CWG 1734的拟议决议,目前处于"就绪"状态,将[class]/p6修改为:
一个简单的可复制类是一个类:
- 其中每个复制构造函数,移动构造函数,复制赋值运算符和移动赋值运算符(12.8 [class.copy],13.5.3 [over.ass])要么被删除,要么是微不足道的,
- 至少有一个未删除的复制构造函数,移动构造函数,复制赋值运算符或移动赋值运算符,以及
- 有一个简单的,未删除的析构函数(12.4 [class.dtor]).
这使得类像
struct B {
B() = default;
B(const B&) = delete;
B& operator=(const B&) = delete;
};
Run Code Online (Sandbox Code Playgroud)
不再是轻易复制的.(这类的类包括像std::atomic<T>和的同步原语std::mutex.)
但是,AOP中有一个隐式声明的,未删除的复制赋值运算符,它是微不足道的,所以它仍然可以轻易地复制.
CWG1734之前情况的原始答案保留在下面以供参考.
是的,有点违反直觉,它是可以轻易复制的.[类]/P6:
一个简单的可复制类是一个类:
- 没有非平凡的复制构造函数(12.8),
- 没有非平凡的移动构造函数(12.8),
- 没有非平凡的副本赋值运算符(13.5.3,12.8),
- 没有非平凡的移动赋值运算符(13.5.3,12.8),和
- 有一个简单的析构函数(12.4).
[class.copy]/P12:
如果不是用户提供的,则类X的复制/移动构造函数是微不足道的,其参数类型列表等效于隐式声明的 参数类型列表,如果
- class X没有虚函数(10.3),没有虚基类(10.1),和
- 类X没有volatile限定类型的非静态数据成员,和
- 选择复制/移动每个直接基类子对象的构造函数是微不足道的,并且
- 对于类类型(或其数组)的X的每个非静态数据成员,选择复制/移动该成员的构造函数是微不足道的;
同样([class.copy]/p25):
如果类X不是用户提供的,则类X的复制/移动赋值运算符是微不足道的,其参数类型列表等效于隐式声明的 参数类型列表,如果
- class X没有虚函数(10.3),没有虚基类(10.1),和
- 类X没有volatile限定类型的非静态数据成员,和
- 选择复制/移动每个直接基类子对象的赋值运算符是微不足道的,并且
- 对于类型(或其数组)的X的每个非静态数据成员,选择复制/移动该成员的赋值运算符是微不足道的;
[class.dtor]/P5:
如果不是用户提供的析构函数是微不足道的,如果:
- 析构函数不是
virtual,- 它的所有直接基类都有琐碎的析构函数
- 对于类类的所有非静态数据成员(或其数组),每个这样的类都有一个简单的析构函数.
[dcl.fct.def.default]/P5:
如果函数是用户声明的,并且在第一个声明中未明确默认或删除,则用户提供该函数.
实际上,这一直是委员会本身存在问题的根源,因为根据当前的定义atomic<T>(以及互斥和条件变量)可以轻易地复制.(很明显,允许某人memcpy超过atomic或mutex不使用UB会......让我们说的是严重问题.)另见N4460.
| 归档时间: |
|
| 查看次数: |
1811 次 |
| 最近记录: |