46

std::atomic_bool異なるスレッドからアクセスされるはずのブール値が必要なため、使用したいと思います。

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

しかし、問題は、コンストラクターとして使用されないことfalseです。では、そのような変数をどのように初期化すればよいのでしょうか? 私はVS2012を使用しています。

4

4 に答える 4

41

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

やあ、

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

STL のアクティブな Connect バグのすべてにこの応答をコピーして貼り付けていますが、次の簡潔なコメントは特にあなたのバグに適用されます。

  • うん、これらのコンストラクターがatomic_bool、などにありませんatomic_int( atomic<bool>atomic<int>などにはあります)。29.5 [atomics.types.generic]/7 は次のように述べてatomic_boolいますatomic<bool>typedefまたは対応する特殊化の基底クラス。基底クラスの場合、対応する特殊化と同じメンバー関数をサポートする必要があります。」これにより、私は本当に typedef を使用したくなります (1 つの型は常に 2 つの型より単純です) が、それによって他の問題が発生するかどうかを確認する必要があります。

このバグをいつ解決できるかはお約束できませんが、できるだけ早く解決したいと考えています (その場合は別の回答をお送りします)。最初の機会は「帯域外」になります。 GoingNative 2012 カンファレンスで Herb Sutter が発表した VC11 と VC12 の間のリリース。

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

Stephan T. Lavavej シニア開発者 - Visual C++ ライブラリ stl@microsoft.com

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

于 2013-04-01T20:13:33.067 に答える
31

これを試して:

atomic_bool my_bool = ATOMIC_VAR_INIT(false);

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

于 2015-07-02T09:35:45.413 に答える
26

問題:

はコピー構築可能ではないため、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
}
于 2013-04-01T20:14:34.070 に答える