11

は何once_flagに初期化されるはずですか? falseとを試しましたが0、どちらも以下のようなエラーが発生しました (以下は0):

no viable conversion from 'int' to 'std::once_flag'

これが私がそれを使用しようとしている方法です。(言語が静的を初期化しても静的を初期化しないのは悪いスタイルだと思うので、そこに何かがあることを本当に望んでいます)。

MyClass& GetMyClass()
{
    static std::once_flag flag;
    static MyClass cls;

    std::call_once(flag, []() {
        // Initialize class
    });

    return cls;
}
4

4 に答える 4

11

アップデート

ドラフト C++ 標準セクション30.4.4.1 Struct once_flagを見ると、コンストラクターが次のように定義されていることがわかります。

constexpr once_flag() noexcept;

これはconstexprであるため、静的インスタンスは静的に初期化され、静的インスタンスを使用する30.4.4.2 関数 call_onceセクションの例を見ることができます。

void g() {
 static std::once_flag flag2;
 std::call_once(flag2, initializer());
}

オリジナル

std::once_flagのドキュメントを見ると、次のように書かれています。

once_flag();

Cnstructs an once_flag object. The internal state is set to indicate that no function
has been called yet. 

さらにcall_onceのドキュメント ドキュメントを参照すると、次の例が使用方法を示していますstd::once_flag

#include <iostream>
#include <thread>
#include <mutex>

std::once_flag flag; 

void do_once()
{
    std::call_once(flag, [](){ std::cout << "Called once" << std::endl; });
}

int main()
{
    std::thread t1(do_once);
    std::thread t2(do_once);
    std::thread t3(do_once);
    std::thread t4(do_once);

    t1.join();
    t2.join();
    t3.join();
    t4.join();
}

次の予想される出力を使用します。

Called once
于 2013-11-15T02:58:58.263 に答える
3

あなたの質問は他の場所で回答されているため、投稿したコードの代わりに、代わりにこれを行うこともできます。

// private function in anonymous namespace or something
MyClass& initMyClass() {
    static MyClass c;
    /* initialize c */
    return c;
}

そして、クライアントに電話してもらいます

MyClass& GetMyClass() {
    static MyClass& c = initMyClass();
    return c;
}

C++11 では静的初期化がスレッドセーフになったためです。そして、いじる必要はありませんcall_once

于 2013-11-15T03:37:26.350 に答える
2

あなたは何をしようとしているのですか?std::once_flag引数を取らないコンストラクターが 1 つしかないため、任意の値で初期化することはできません。

http://en.cppreference.com/w/cpp/thread/once_flag

once_flag(); once_flag オブジェクトを構築します。内部状態は、関数がまだ呼び出されていないことを示すように設定されます。

ところで、静的変数を初期化しないことが悪いスタイルだと考える理由は何ですか?

于 2013-11-15T02:59:05.137 に答える
1

ONCE_FLAG_INIT

編集: C のみ、C++ ではありません。で定義されてい<threads.h>ます。

于 2013-11-15T03:00:23.533 に答える