std::atomic<std::shared_ptr<Struct Demo>>是否可以安全地与 C++11 一起使用,因为上述部分专用化仅适用于 C++20?

Could std::atomic<std::shared_ptr<Struct Demo>> could be safely used with C++11 since the said partial specializations is only available with C++20?

提问人:John 提问时间:10/8/2023 最后编辑:Jan SchultkeJohn 更新时间:10/9/2023 访问量:92

问:

根据 cppreference 上的 std::atomic 文章,其中说(强调我的):

在标头中定义<atomic>

template< class T >
struct atomic; // (since C++11)
template< class U >
struct atomic<U*>; // (since C++11)

在标头中定义<memory>

template< class U >
struct atomic<std::shared_ptr<U>>; // (since C++20)

template< class U >
struct atomic<std::weak_ptr<U>>; // (since C++20)

尽管 的部分专用化仅适用于 C++20,但可以安全地用于 C++11 吗?std::shared<T>std::atomic<std::shared_ptr<Struct Demo>>

是否有任何我应该注意的潜在问题?

C++ C++11 互斥 原子 共享 PTR

评论

1赞 Raymond Chen 10/8/2023
T必须是微不足道的可复制的,但事实并非如此。shared_ptr
0赞 John 10/8/2023
@RaymondChen 你能告诉我你在哪里看到这样的要求吗?我真的看不到cppreferences在std::atomic中的任何提示
2赞 Raymond Chen 10/8/2023
“如果以下任何值为 false,则程序格式不正确:...”std::is_trivially_copyable<T>::value

答:

1赞 user17732522 10/8/2023 #1

不,主模板要求是可简单复制的,但事实并非如此。std::atomic<T>Tstd::shared_ptr

尝试在 C++20 之前使用它将无法编译。

评论

0赞 Peter Cordes 10/8/2023
事实上,godbolt.org/z/1qjGahheG 如果您不使用 或更高(或 )。因此,即使在实践中,具有专用化的当前标准库头文件也不会启用它,除非您设置了足够新的 C++ 版本来需要它。(关于“潜在问题”的问题是没有意义的,因为它甚至不会编译,除非有一些不同的编译器。-stdlib=libc++-std=gnu++20-std=c++20
0赞 user17732522 10/8/2023
@PeterCordes 是的,根据标准(C++20 之前),实例化该专用化会使程序格式不正确,这意味着诊断是强制性的,并且在实践中意味着编译器在编译时会出错。符合要求的编译器可以在 C++ 之前的模式下支持它,但至少必须警告用户有关使用,然后行为将完全取决于实现。因此,即便如此,回答它是否总体上是“安全的”也是没有意义的。
0赞 John 10/8/2023
@Peter Cordes C++14 也不适用于上述含义?在 C++14 中,放宽了对 std::atomic<T> 的基础类型 T 的简单可复制性的要求。 从 C++14 开始,std::atomic 支持非平凡的可复制类型,只要它们满足某些要求。基础类型 T 必须同时是可复制和可赋值的,这意味着它必须定义复制构造函数和赋值运算符。
0赞 Peter Cordes 10/8/2023
@John:您可以通过编辑 Godbolt 链接上的命令行参数来自己尝试一下。但是不,godbolt.org/z/s67jjfb6G 表明这并没有改变任何事情。实际的错误消息是它不是可轻易复制的;如果它们支持非平凡的可复制类型,则可能有一个单独的专用化或检查已经失败。-std=gnu++14
2赞 user17732522 10/8/2023
@John 不知道你从哪里得到这句话,但这完全是错误的。
1赞 Jan Schultke 10/8/2023 #2

不,将违反约束,因为根据 [atomics.types.generic] p1std::atomic<std::shared_ptr<T>>

模板参数的类型应易于复制 ([basic.types]T)

注意:此要求在 C++20 ([atomics.types.generic.general]) 到 LWG3012 中更加严格:atomic<T> 对于非 is_trivially_copy_constructible T 是不可实现的,但它不适用于智能指针的部分专用化 ([util.smartptr.atomic])。

std::shared_ptr不是轻而易举的可复制的,因此它不能与 一起使用。std::atomic

但是,std::shared_ptr<std::atomic<T>>> 只是一个 API 改进。在 C++20 之前,可以使用实用程序函数,例如 std::atomic_load(const std::shared_ptr*)。例如:

std::shared_ptr<int> value = std::atomic_load(&my_pointer);
// or, with explicit memory order
std::shared_ptr<int> value = std::atomic_load_explicit(&my_pointer, std::memory_order_relaxed);

Смотритетакже: std::shared_ptr 和 std::atomic<std::shared_ptr> 又名 std::experimental::atomic_shared_ptr有什么区别?