33

アトミックメンバー変数を持つクラスがあります:

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

移動コンストラクターはどのように見えるべきですか?

std::move()Gcc 4.7は私の試み(の周りに追加するなど)のどれも好きではなくother.bar、ネットはここでは驚くほど静かです...

4

3 に答える 3

32

std::atomicコピーコンストラクターが削除され、移動コンストラクターが定義されていないため、コピー可能または移動可能ではありません。gustafの回答で指摘されているように、他の値を明示的にロードし、それを使用して新しい値を作成する必要があります。

なぜ動かstd::atomicないのですか?これは同期プリミティブであるため、すべてのスレッドは同じデータ(つまり、同じアドレス)で同期する必要があります。アトミック値をコピー(または移動)するときは、何らかの通信プロトコルを使用する必要があります。あなたの例のように単純かもしれませんが(ロードして新しいアトミックを初期化するために使用するだけです)、一般的に、C++11による設計上の決定として考えさせるのは良いことだと思います。そうしないと、コードは正常に見えるかもしれませんが、いくつかの微妙な同期の問題があります。

于 2013-01-06T14:21:03.297 に答える
19

あなたが移動しているのでother、他の誰もそれにアクセスしません。したがってbar、アトミックであるかどうかに関係なく、その読み取りは安全です。

atomic<T>コンストラクターは2つだけで、1つはデフォルト()で、もう1つはです(T)。したがって、コードはコンパイルする必要があるように見えます。そうでない場合は、static_castother.barをにキャストしてT(T)コンストラクターを強制的に使用するとどうなりますか?

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

または、これは同等で、おそらく醜いものではありません。

: bar( other.bar.load( ) )

于 2013-01-06T13:05:54.917 に答える
2

のテンプレートインスタンス化は、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));
于 2013-01-06T15:46:23.407 に答える