27

私は以下のようなクラスを持っています。

#include <atomic>

static const long  myValue = 0;

class Sequence
{

public:

    Sequence(long initial_value = myValue) : value_(initial_value) {}


private:

     std::atomic<long> value_;
};

int main()
{
         Sequence firstSequence;
         Sequence secondSequence = firstSequence;
         return 0;
}

このようなコンパイルエラーが発生します、

test.cpp:21:36: error: use of deleted function ‘Sequence::Sequence(const Sequence&)’
test.cpp:5:7: error: ‘Sequence::Sequence(const Sequence&)’ is implicitly deleted because the default definition would be ill-formed:
test.cpp:5:7: error: use of deleted function ‘std::atomic<long int>::atomic(const std::atomic<long int>&)’

このような場合、デフォルトのコピーコンストラクターと割り当て演算子は機能しませんか?

PS:私はgccバージョン4.6.3を使用しています

4

4 に答える 4

26

すべてのロードとストアは明示的に行われる必要があるため、標準のコピーコンストラクターを使用してアトミックをコピーすることはできません。Sequenceフォームの初期化を行う独自のコピーコンストラクターを作成する必要がありますvalue_(rhs.value_.load())(おそらく、よりリラックスしたメモリ順序で)。

于 2012-08-17T09:24:59.523 に答える
8

Atomicはcopy-ctorを削除しました。したがって、クラス内のコピー/移動-ctorsは削除されます。

n3337 12.8 / 11

暗黙的に宣言されたコピー/移動コンストラクターは、そのクラスのインラインパブリックメンバーです。クラスXのデフォルトのコピー/移動コンストラクターは、Xに次の場合、削除済み(8.4.3)として定義されます。

—クラスタイプM(またはその配列)の非静的データメンバー。Mの対応するコンストラクターに適用されるオーバーロード解決(13.3)により、あいまいさや関数が削除されたり、アクセスできなくなったりするため、コピー/移動できません。デフォルトのコンストラクター、

于 2012-08-17T09:27:23.570 に答える
7

std::atomic<long int>::atomic(const std::atomic<long int>&)関数がないため、コンパイラがクラスのデフォルトのコピーコンストラクタを作成する方法はありませんSequence。そのクラスのコピーコンストラクターが必要な場合(そして作業したい場合はSequence secondSequence = firstSequence;必要です)、それを作成する必要があります。

この動作は、標準で要求されています。

アトミック積分とアドレスタイプを以下に示します。これらのタイプは標準レイアウトでなければなりません。それらには、些細なデフォルトコンストラクタ、constexpr明示値コンストラクタ、削除されたコピーコンストラクタ、削除されたコピー代入演算子、および些細なデストラクタが必要です。これらのタイプは、集約初期化構文をサポートする必要があります。

于 2012-08-17T09:22:11.803 に答える
2

標準でコピーコンストラクターを削除するという選択は、次の2つの理由によると思います。

  • 一般に、ロード/ストアのペアが必要です。std :: atomicの呼び出し元を制御しない場合に、これが実行されるように強制する方法はありますか?

  • 使用していたstd::atomic <>タイプがis_lock_free()がfalseのタイプであった場合(つまり、そのサイズの整数タイプの実装ではミューテックスが必要)、どうしますか?ミューテックスの初期化にはどのコピーセマンティクスを使用しますか?暗黙的にコピーされたミューテックスは、ロックされた状態で不幸にもコピーされる可能性があるため、再初期化する必要があります。このため、std :: mutexにもコピーコンストラクターが削除されていると思います。これにより、要件がstd::atomicにもプッシュされます。

于 2013-03-22T20:45:22.377 に答える