在 msvs 2013 中 std::shared_ptr 的 compare_exchange_weak 是不是损坏?
Posted
技术标签:
【中文标题】在 msvs 2013 中 std::shared_ptr 的 compare_exchange_weak 是不是损坏?【英文标题】:is compare_exchange_weak for std::shared_ptr broken in msvs 2013?在 msvs 2013 中 std::shared_ptr 的 compare_exchange_weak 是否损坏? 【发布时间】:2013-12-27 17:48:17 【问题描述】:请看样例
std::atomic < std::shared_ptr < int > > a;
std::shared_ptr < int > b;
std::shared_ptr < int > c = std::make_shared < int > (10);
while(a.compare_exchange_weak(b, c));
assert(a.load() == c);
assert(a.load().use_count() == 2); // <- assertion is failed.
你怎么看?是编译器错误吗?
在 win32 模式下使用 msvs 2013 构建
【问题讨论】:
Herb Sutter 有一个针对 atomic_shared_ptr 的 C++(17?) 标准设计提案,该文档还解释了现有方法的缺点:open-std.org/jtc1/sc22/wg21/docs/论文/2014/n4162.pdf Спасибо, Максим, отличная статья Спасибо Гербу Саттеру ;-) 【参考方案1】:您的程序表现出未定义的行为。
29.5/1 有一个通用类模板
atomic<T>
。模板参数T
的类型应该是可简单复制的 (3.9)。
shared_ptr<int>
不可轻易复制。
【讨论】:
这个答案在 C++20 之前是正确的。有关它在 C++20 中如何更改的详细信息,请参阅此页面上的 this answer。【参考方案2】:根据 Igor 的回答,std::atomic<std::shared_ptr<T>>
没有定义的行为。您需要使用 C++11 §20.7.2.5 shared_ptr
原子访问 [util.smartptr.shared.atomic] 中详述的 the non-member shared_ptr
atomic function overloads。
std::shared_ptr < int > a;
std::shared_ptr < int > b;
std::shared_ptr < int > c = std::make_shared < int > (10);
while(std::atomic_compare_exchange_weak(&a, &b, c))
;
assert(std::atomic_load(&a) == c);
assert(std::atomic_load(&a).use_count() == 2);
我觉得奇怪的是,该标准并未要求使用这些函数实现 template <typename T> struct std::atomic<shared_ptr<T>>
的部分特化。
我在Microsoft's documentation of the <memory>
header 中没有看到非成员原子重载,因此它们可能不会在 VS2013 中实现。
【讨论】:
这个答案在 C++20 之前是正确的。有关它在 C++20 中如何更改的详细信息,请参阅此页面上的 this answer。【参考方案3】:问题是关于 C++11,但值得指出的是,因为 C++20 OP 代码是有效的,因为 shared_ptr
和 @ 都有专门的 std::atomic
987654325@.
见:std::atomic<std::shared_ptr<T>>
at cppreference
另外,使用std::atomic_compare_exchange
的替代方法是deprecated in C++20。
【讨论】:
以上是关于在 msvs 2013 中 std::shared_ptr 的 compare_exchange_weak 是不是损坏?的主要内容,如果未能解决你的问题,请参考以下文章
“预定义”和使用命名空间和 std::shared_ptr 的正确方法是啥?
一台计算机中的 msvs 2013 错误 C2057,另一台计算机中没有错误。这是怎么回事?
在 c++11 中转换 std::future 或 std::shared_future