[英]How to ensure std::call_once really is only called once
我正在使用的一些代碼使用std :: call_once,因此一些初始化只發生一次。 但是,有些構造函數的全局對象最終可能會調用初始化代碼。
在下面的示例中,call_once實際上被調用了兩次。 我想這是因為once_flag構造函數在使用之前沒有運行過。 有沒有辦法解決這個問題,以便一些初始化代碼只被調用一次而不必禁止全局變量?
#include <mutex>
#include <iostream>
using namespace std;
void Init();
class Global
{
public:
Global()
{
Init();
}
};
Global global;
once_flag flag;
void Init()
{
call_once(flag, []{ cout << "hello" << endl; });
}
int main(int argc, char* argv[])
{
Init();
return 0;
}
輸出是:
hello
hello
根據規范, once_flag
應該有一個簡單的constexpr
構造函數(例如見這里 - http://en.cppreference.com/w/cpp/thread/once_flag )。 有了它,如果它是全局/靜態的,它實際上不是“構造的”(沒有執行實際的函數),而更像是“值初始化” - 就像任何全局/靜態POD類型一樣。 在這種情況下,不可能在“before”之前運行任何構造函數,這個once_flag
被正確初始化。 鑒於您對使用MSVC的評論,我想這可能是實施中的一個錯誤......
編輯:根據下面的評論,在MSVC上根本不支持constexpr
,所以你的選項在這里真的有限......如果你把所有東西放在一個文件中,只需把你的once_flag
“置於”使用它的所有東西 - 構造函數在文件中按對象聲明的順序執行。 如果您的用戶分布在不同的文件中,您唯一的選擇就是使用一個提供靜態內部once_flag
訪問權限的函數 - 就像在這個答案中一樣http://www.parashift.com/c++-faq/static-init-order- on-first-use.html 。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.