web-dev-qa-db-ja.com

std :: atomic_boolを初期化していますか?

std::atomic_boolを使用したいのは、異なるスレッドからアクセスされることになっているブール値が必要だからです。

これはstaticメンバー変数です。問題は、falseを最初の状態として初期化することです。通常、私はそのようにします:std::atomic_bool World::mStopEvent = false;

しかし、問題はfalseをコンストラクターとして受け取らないことです。では、このような変数をどのように初期化するのでしょうか? VS 2012を使用しています。

39
Sapd

これは Visual Studio 2012の既知の問題(VC11) です。既存のConnectアイテムに投票する必要があります。Microsoftが修正を延期しているため、より多くの人々に影響があることを知っているためです。

こんにちは、

このバグを報告していただきありがとうございます。私はMicrosoftのSTLのメンテナーです。このバグはデータベースでアクティブのままですが、VC11 RTM(VS 2012 RTM)では修正されません。すべてのバグは私たちにとって重要ですが、一部のバグは他のバグよりも深刻であり、優先度キューのトップに上がります。

STLのアクティブなConnectのすべてのバグにこの応答をコピーアンドペーストしていますが、次の簡潔なコメントが特にバグに適用されます。

  • ええ、atomic_boolatomic_intなどにこれらのコンストラクターがありません(atomic<bool>atomic<int>などにはそれらがあります)。 29.5 [atomics.types.generic]/7は、「表145に指定されているように、atomicの整数の特殊化に対応する名前付き型と、指定されたatomic_boolに対応する名前付き型atomic<bool>各名前付き型は、対応する特殊化のtypedefまたは対応する特殊化の基本クラスのいずれかです。基本クラスの場合、対応する特殊化と同じメンバー関数をサポートします。 typedef(1つの型は常に2つの型よりも常に単純です)を使用したいのですが、他の問題が発生するかどうかを確認する必要があります。

このバグを解決できるとは約束できませんが、できるだけ早く解決したいと考えています(そして、それが起こったら別の応答を送信します)-最初の機会は「帯域外」ですハーブサッターがGoingNative 2012カンファレンスで発表したVC11とVC12の間のリリース。

注:Connectはコメントについて通知しません。さらに質問がある場合は、私にメールしてください。

Stephan T. Lavavejシニア開発者-Visual C++ライブラリ[email protected]

基本的に、今のところstd::atomic<T>を使用する必要があります。

38
user7116

これを試して:

atomic_bool my_bool = ATOMIC_VAR_INIT(false);

http://en.cppreference.com/w/cpp/atomic/ATOMIC_VAR_INIT

23
andrewrk

問題:

_std::atomic_bool_はコピー構築できないため、copy-initializationは使用できません。

_std::atomic_bool World::mStopEvent = false; // ERROR!
_

実際、上記は次と同等です。

_std::atomic_bool World::mStopEvent = std::atomic_bool(false); // ERROR!
_

ただし、direct-initializationを使用できます。

_std::atomic_bool World::mStopEvent(false);
_

必要に応じて、括弧の代わりに中括弧を使用することもできます。

_std::atomic_bool World::mStopEvent{false};
_

バグ:

どのコンパイラを選択してもコピーの初期化は違法ですが、VC11に同梱されている標準ライブラリの実装にはバグがあり、直接初期化も実行できないようです。

それでは、このような変数をどのように初期化するのでしょうか?

回避策:

可能な回避策として、アトミックブールフラグの値を設定および返す静的ゲッター/セッターラッパーのペアを提供できます。スレッドセーフな方法で望ましい初期値(これはある種の遅延初期化と考えることができます):

_#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
}
_
20
Andy Prowl

どうですか:

std::atomic_bool World::mStopEvent(false);
2
Bill Lynch