什么是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;
}
答案 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
BTW,你认为不初始化静态变量的原因是什么?once_flag();构造一个once_flag对象。内部状态已设置 表示尚未调用任何功能。
答案 3 :(得分:1)
ONCE_FLAG_INIT
编辑:仅限C,而不是C ++。定义在<threads.h>
。