【问题标题】:Why can't std::atomic<T> be swapped?为什么不能交换 std::atomic<T> ?
【发布时间】:2020-05-07 11:20:19
【问题描述】:
#include <atomic>

int main()
{
    auto a = std::atomic_int(1);
    auto b = std::atomic_int(2);

    std::swap(a, b); // error
}

错误信息:

错误:没有匹配函数调用 'swap(std::atomic&, std::atomic&)'

为什么不能交换std::atomic&lt;T&gt;

【问题讨论】:

  • 通过std::swap 交换不会是原子的,但我想知道为什么它没有成员swap...
  • 交换它们时不需要是原子的。
  • 相关? Atomic exchange of two std::atomic<T*> objects in a lock-free manner in C++11?; “问题是不可能跨两个原子对象进行原子操作,[...]”.
  • atomic 不需要是原子的时候,为什么要首先使用它?考虑两个线程同时交换。单独的读写是原子的,但是交换后的结果可能会搞砸
  • 例如在 move-ctor 中,成员变量是原子的。 @idclev463035818

标签: c++ c++11 std standards atomic


【解决方案1】:

std::atomic 有一个已删除的复制构造函数,并且没有移动构造函数。

因此它既不是move assignable也不是move constructible

因此,std::swap 不能在任何 std::atomic 类型上调用。

参考:

https://en.cppreference.com/w/cpp/algorithm/swap

【讨论】:

  • a.exchange(b.exchange(a)); 怎么样?
【解决方案2】:

这个问题有两个层面。

首先是简单而技术性的 - std::atomic 不能像其他答案中提到的那样移动构造或移动分配。

其次是这背后的基本原理——交换std::atomics 本身并不是原子的。并且由于std::atomics 用于多线程环境,添加swap 会由于可能的误解而导致广泛的错误(因为std::atomicswap,所以它本身就是原子的)。

总而言之 - 如果您不需要原子 swap,这可以很容易地使用提到的 exchanges 来完成。

【讨论】:

  • 根据你的最后一段,我觉得这有点成为一个动机问题。更重要的是 - std::swap 在每种情况下基本上都是双重移动它只是交换两个值?如果是后者,我认为没有理由不完全像两个 exchange 调用那样实现它。不是试图在这里找到答案,而是试图大声说出潜在的问题。
猜你喜欢
  • 1970-01-01
  • 2021-06-21
  • 2018-11-22
  • 2020-03-08
  • 1970-01-01
  • 1970-01-01
  • 2014-05-05
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多