2013-04-01 267 views
35

我想使用std::atomic_bool,因爲我想要一個布爾值,它應該被不同的線程訪問。初始化std :: atomic_bool?

這是一個static成員變量。問題是我想用false作爲第一個狀態來初始化它。通常我會這樣做: std::atomic_bool World::mStopEvent = false;

但問題似乎是它不需要false作爲構造函數。那麼我應該如何初始化這樣一個變量? 我使用VS 2012

回答

36

這是一個known issue in Visual Studio 2012 (known as VC11),你應該在現有的連接項目讓微軟知道它會影響更多的人,因爲他們已經推遲修復投票。

Hi,

Thanks for reporting this bug. I'm Microsoft's maintainer of the STL, and I wanted to let you know that while this bug remains active in our database, it won't be fixed in VC11 RTM (VS 2012 RTM). All bugs are important to us, but some are more severe than others and rise to the top of our priority queue.

I'm copying-and-pasting this response across all of the STL's active Connect bugs, but the following terse comments apply specifically to your bug:

  • Yep, we're missing these constructors on atomic_bool , atomic_int , etc. (atomic<bool> , atomic<int> , etc. have them). 29.5 [atomics.types.generic]/7 says "There shall be named types corresponding to the integral specializations of atomic, as specified in Table 145, and a named type atomic_bool corresponding to the specified atomic<bool> . Each named type is a either typedef to the corresponding specialization or a base class of the corresponding specialization. If it is a base class, it shall support the same member functions as the corresponding specialization." which makes me really want to use typedefs (1 type is always simpler than 2 types), but I'll need to see if that would introduce any other issues.

I can't promise when we'll be able to resolve this bug, but we hope to do so as soon as possible (and I'll send another response when that happens) - our first opportunity will be the "out of band" release between VC11 and VC12 that Herb Sutter announced at the GoingNative 2012 conference.

Note: Connect doesn't notify me about comments. If you have any further questions, please E-mail me.

Stephan T. Lavavej Senior Developer - Visual C++ Libraries [email protected]

基本上,您現在需要使用std::atomic<T>

2

如何:

std::atomic_bool World::mStopEvent(false); 
+3

同樣的錯誤: '錯誤C2440:初始化:不能從轉換' bool'改爲'std :: atomic_bool' 1>沒有構造函數可以採用源類型,或者構造函數重載解析模糊不清[ – Sapd

20

問題:

不能使用複製初始化,因爲std::atomic_bool不是拷貝構造:

std::atomic_bool World::mStopEvent = false; // ERROR! 

其實,上面的是等價於:

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

但是,您可以使用direct-initiali矩陣特殊積

std::atomic_bool World::mStopEvent(false); 

在你的願望,你可以選擇,而不是使用圓括號的括號:

std::atomic_bool World::mStopEvent{false}; 

BUG:

雖然副本初始化是非法的,無論是什麼編譯器,你選擇,似乎VC11附帶的標準庫的實現有一個錯誤,不會讓你執行直接初始化。

So how I am supposed to initialize such a variable?

解決方法:

作爲一種可能的解決辦法,可以提供一對靜態的getter/setter包裝是的 - 分別 - 設置並返回原子布爾標誌的值,但並未成爲前確定它已經被初始化至少一次,並且不超過一次在一個線程安全的方式所需的初始值(可以考慮一下這款某種延遲初始化的):

#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 
} 
+0

]是的,直接初始化不起作用:( – Sapd

+1

@Sapd:我試圖提供一種解決方法,希望它有幫助 –

+0

是的,謝謝,我想使用訪問器。可惜這個開銷是需要的。 – Sapd

16

試試這個:

atomic_bool my_bool = ATOMIC_VAR_INIT(false); 

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

+1

我認爲這是這裏最好的答案,因爲它可以以最短的方式解決問題,而且沒有開銷。此解決方案也是跨平臺的,我在VS和Xcode中進行了補充。 – GuidC0DE

+0

是的,在Mac OS X上與Clang一起編譯,但警告標記初始化程序[-Wbraced-scalar-init]的括號。當然,如果你啓用它。 – dismine