std::atomic_int
変数を使用したい。私のコードには、次のものがあります。
#include <atomic>
std::atomic_int stop = 0;
int main()
{
// Do something
}
そして、これは私にコンパイルエラーを与えます:
use of deleted function 'std::__atomic_base<_IntTp>::__atomic_base(const std::__atomic_base<_IntTp>&) [with _ITp = int]'
std::atomic_int stop = 0;
^
何が起こっているのか考えていますか?
コードは一時的なstd::atomic_int
RHSでは、std::atomic_int
コンストラクター(delete
d)をコピーして、stop
を初期化します。
std::atomic_int stop = std::atomic_int(0);
これは、ここで実行しているcopy-initialisationは、他の種類の初期化とまったく同じではないためです。
[C++11: 8.5/16]:
初期化子のセマンティクスは次のとおりです[..]初期化子が(括弧なしの)braced-init-listである場合、オブジェクトまたは参照はlist-initialized(8.5.4)です。
(これにより、この回答の最後にオプション3が可能になります)
[..]
宛先タイプが(おそらくcv修飾された)クラスタイプの場合:
- 初期化がdirect-initializationの場合、またはcopy-initializationの場合cv-unqualified version ofソースタイプは、宛先のクラスと同じクラス、またはその派生クラスであり、コンストラクターが考慮されます。適用可能なコンストラクターが列挙され(13.3.1.3)、最適なものがオーバーロード解決(13.3)によって選択されます)。そのように選択されたコンストラクターは、引数として初期化式または式リストを使用して、オブジェクトを初期化するために呼び出されます。コンストラクターが適用されない場合、またはオーバーロード解決があいまいな場合、初期化の形式は正しくありません。
(これはほとんどあなたのコードを説明していますが、完全ではありません。ここで重要なのは、おそらく直感に反して、std::atomic_int
のコンストラクタは、あなたの場合はまったく考慮されません!)
- それ以外の場合(つまり、残りのcopy-initializationの場合)、ソースタイプから宛先タイプに変換できるユーザー定義の変換シーケンス、または(変換の場合13.3.1.4で説明されているように、その派生クラスへの関数が列挙され、最適なものがオーバーロード解決(13.3)によって選択されます。変換が実行できないかあいまいな場合、初期化は不正です。 =選択された関数は、引数として初期化式を使用して呼び出されます。関数がコンストラクターである場合、呼び出しは宛先タイプのcv非修飾バージョンの一時を初期化します。一時はprvalueです。 呼び出しの結果(コンストラクターの場合の一時的なもの)は、上記の規則に従ってdirect-initializeに使用され、 copy-initializationの宛先。特定の場合、実装は、このdirect-initialization中間結果を初期化中のオブジェクトに直接構築する。 12.2、12.8を参照してください。
(これはあなたのシナリオです;したがって、コピーは省略できますが、それはまだ可能でなければなりません)
- [..]
とにかく、ここに修正があります。 direct-initialisationまたはlist-initialisationを使用します。
std::atomic_int stop(0); // option 1
std::atomic_int stop{0}; // option 2
std::atomic_int stop = {0}; // option 3