繁体   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