簡體   English   中英

如何確保std :: call_once真的只調用一次

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM