初始化once_flag?

时间:2013-11-15 02:53:40

标签: c++ c++11

什么是once_flag应该初始化为什么?我们尝试了false0,两者都给出了类似于下面的错误(下面是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 个答案:

答案 0 :(得分:7)

更新

如果我们查看草案C ++标准部分30.4.4.1 Struct once_flag ,我们可以看到构造函数定义为:

constexpr once_flag() noexcept;

因为它是 constexpr 静态实例将静态初始化,我们可以在30.4.4.2 <部分中看到一个示例em>使用静态实例的函数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

答案 1 :(得分:2)

由于您的问题已在其他地方得到解答,作为您发布的代码的替代方法,您也可以这样做:

// 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或任何东西。

答案 2 :(得分:1)

你想做什么?您无法使用任何值初始化std::once_flag,因为它只有一个不带任何参数的构造函数。

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

  

once_flag();构造一个once_flag对象。内部状态已设置   表示尚未调用任何功能。

BTW,你认为不初始化静态变量的原因是什么?

答案 3 :(得分:1)

ONCE_FLAG_INIT

编辑:仅限C,而不是C ++。定义在<threads.h>