問題:
はコピー構築可能ではないため、copy-initializationは使用できません。std::atomic_bool
std::atomic_bool World::mStopEvent = false; // ERROR!
実際、上記は次と同等です。
std::atomic_bool World::mStopEvent = std::atomic_bool(false); // ERROR!
ただし、直接初期化を使用できます。
std::atomic_bool World::mStopEvent(false);
必要に応じて、括弧の代わりに中括弧を使用することもできます。
std::atomic_bool World::mStopEvent{false};
バグ:
どのコンパイラを選択してもコピー初期化は違法ですが、VC11 に同梱されている標準ライブラリの実装にはバグがあり、直接初期化も実行できないようです。
では、そのような変数をどのように初期化すればよいのでしょうか?
回避策:
考えられる回避策として、アトミック ブール値フラグの値をそれぞれ設定および返す静的な getter/setter ラッパーのペアを提供できますが、少なくとも 1 回以上初期化されていないことを確認する前ではありません。スレッドセーフな方法で必要な初期値 (これはある種の遅延初期化と見なすことができます):
#include <atomic>
#include <mutex>
struct World
{
static bool is_stop_event_set()
{
std::call_once(mStopEventInitFlag, [] () { mStopEvent = false; });
return mStopEvent;
}
static void set_stop_event(bool value)
{
std::call_once(mStopEventInitFlag, [value] () { mStopEvent = value; });
mStopEvent = value;
}
static std::atomic_bool mStopEvent;
static std::once_flag mStopEventInitFlag;
};
std::atomic_bool World::mStopEvent;
std::once_flag World::mStopEventInitFlag;
直接アクセスする代わりにmStopEvent
、その値はis_stop_event_set()
関数を介して読み取られます。
#include <iostream>
int main()
{
std::cout << World::is_stop_event_set(); // Will return false
}