C ++ 11:写移动的构造与原子 会员?(C++11: write move constru

2019-08-05 18:20发布

我有与原子成员变量的类:

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

如何应该是移动的构造是什么样子?

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

Answer 1:

既然你移动other ,没有人会访问它。 所以从它的读bar是安全的,羯羊它的原子或没有。

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

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

或等于,也许少难看:

: bar( other.bar.load( ) )



Answer 2:

std::atomic ,因为是不可拷贝或移动它的拷贝构造函数被删除 ,并没有转移构造函数的定义。 你必须明确地加载其他值,并用它构建新的价值,因为它是在古斯塔夫的回答指出。

为什么std::atomic不移动? 由于它是一个同步原语,所有线程都在相同的数据(即,同一个地址)同步。 当复制(或移动)的原子值,则必须使用一些通信协议。 它可以是简单的,因为在你的例子(只是加载并使用它来初始化新的原子),但总的来说,我认为这是一个很好的设计决策,由C ++ 11,迫使你不得不去想它。 否则,它可能会导致代码看起来不错,但有一些微妙的同步问题。



Answer 3:

的模板实例atomic<bool>本质是这样的:

struct atomic<bool>
{
    atomic<bool>(bool);
    atomic<bool>( const atomic<bool>& ) = delete;
    operator bool() const;
}

所以,当您尝试复制它:

atomic<bool> a = ...;
atomic<bool> b(a);

被删除的拷贝构造函数选择,并导致编译错误。

您需要显式转换为bool要经过operator bool() --> atomic<bool>(bool) ...

atomic<bool> a = ...;
atomic<bool> b(bool(a));


文章来源: C++11: write move constructor with atomic member?