C++ 11:使用atomic <bool>成员编写移动构造函数?

Chr*_*ris 28 c++ atomic libstdc++ move-semantics c++11

我有一个带有原子成员变量的类:

struct Foo
{
  std::atomic<bool> bar;
  /* ... lots of other stuff, not relevant here ... */
  Foo() 
  : bar( false )
  {}

  /* Trivial implementation fails in gcc 4.7 with:
   *   error: use of deleted function ‘std::atomic<bool>::atomic(const td::atomic<bool>&)’
   */
  Foo( Foo&& other )
  : bar( other.bar )
  {}
};

Foo f;
Foo f2(std::move(f));  // use the move
Run Code Online (Sandbox Code Playgroud)

移动构造函数应该怎么样?

GCC 4.7不喜欢我的任何企图(如添加std::move()周围other.bar)和净是出奇的安静这里...

Phi*_*ßen 27

std::atomic是不可复制的或可移动的,因为它的复制构造函数被删除,并且没有定义移动构造函数.您必须显式加载其他值并使用它构造新值,正如gustaf的回答中所指出的那样.

为什么std::atomic不动?由于它是同步原语,所有线程必须在相同的数据(即,相同的地址)上同步.复制(或移动)原子值时,必须使用某种通信协议.它可能很简单,就像在您的示例中一样(只需加载它并使用它来初始化新原子)但是,一般来说,我认为C++ 11强制您考虑它是一个很好的设计决策.否则,它可能会导致代码看起来很好,但有一些子实体同步问题.

  • 我试图找出一种情况,当您有多个线程时,自动移动原子实际上可能会出现问题。使用 std::move() 手动强制移动是另一回事。无论哪种方式,我都想要一个例子来说明移动原子在哪里会出现问题。您可以移动任何其他 `std` 容器,并且您应该负责同步。 (2认同)

gus*_*f r 17

由于你正在移动other,没有其他人会访问它.因此,阅读它bar是安全的,不管它是原子的还是非原子的.

atomic<T>只有两个构造函数,一个是默认值(),另一个是默认值(T).所以,你的代码看起来应该编译.如果没有,如果你使用static_cast other.barT强制执行(T)构造函数会发生什么?

: bar( static_cast< bool >( other.bar ) )

或者等于,也许不那么难看:

: bar( other.bar.load( ) )

  • _所以,你的代码看起来应该编译.不,`atomic <T>`有一个删除的拷贝构造函数,重载决议发现不是`atomic(T)`构造函数.铸造或装载是必要的. (8认同)
  • 不,原因是调用的最佳匹配是复制构造函数,因此重载决策选择了.删除的函数不**意味着"忽略此函数"意味着"如果调用此函数,则程序无法编译" (4认同)