std::atomic<T>::operator= 如何为不可变类型实现?

Ben*_*y K 1 c++ thread-safety exception-safety stdatomic

我了解到线程之间通信的一种方法是共享一些原子数据结构。例如:

struct Point {
    int const x, y;
};

std::atomic<Point> some_point_in_shared_memory{Point{0, 0}};
Run Code Online (Sandbox Code Playgroud)

尽管Point::operator=(Point const &)被删除,但调用赋值运算符似乎没有问题std::atomic<Point>,如下所示:

some_point_in_shared_memory = Point{1, 2};
Run Code Online (Sandbox Code Playgroud)

如何实施此操作?

我可能会想到的一种解决方案是使用placement new在旧对象之上构造一个新对象,但显然它不是异常安全的。还是因为Point可以简单地复制而没关系?

for*_*818 6

cppreference

主 std::atomic 模板可以用任何满足 CopyConstructible 和 CopyAssignable 的 TriviallyCopyable 类型 T 实例化。如果以下任何一个值为 false,则程序格式错误:

std::is_trivially_copyable<T>::value
std::is_copy_constructible<T>::value
std::is_move_constructible<T>::value
std::is_copy_assignable<T>::value
std::is_move_assignable<T>::value
Run Code Online (Sandbox Code Playgroud)

T不是 CopyAssignable,这一行

some_point_in_shared_memory = Point{1, 2};
Run Code Online (Sandbox Code Playgroud)

是畸形的。应该是编译器错误。不幸的是,我没有让 GCC 发出错误或警告(-pedantic -Wpedantic -pedantic-errors -Wall -Werror=pedantic无效)。