在函数静态变量上调用setter一次

时间:2017-12-07 13:46:38

标签: c++ multithreading c++11 static

我使用函数静态变量,我想通过调用setter来初始化一次:

void foo() {
    static Obj obj;
    obj.setName("name"); // this should be called once
    // use obj
}

我不希望多次调用setter,也是由于多线程问题而且我无法向Obj添加构造函数,因为我不拥有代码。这是合理且线程安全的:

void foo() {
    static Obj obj = []() {
        Obj o;
        o.setName("name");
        return o;
    }();
    // use obj
}

1 个答案:

答案 0 :(得分:1)

是的,这是线程安全的。引用n3337 - [stmt.dcl]/4,强调我的:

  

...这样的变量在第一次控制传递时被初始化   通过宣言;这样的变量被认为是初始化的   在初始化完成后。如果初始化退出   通过抛出异常,初始化不完整,所以它   下次控制进入声明时将再次尝试。 如果   控件在变量的同时输入声明   在初始化时,并发执行应等待完成   初始化。

您从lambda的返回值执行复制初始化,但它并不重要。上面的段落不会将obj的初始化限制为值或直接初始化。所有形式的初始化都适用。

作为旁注,如果你必须应对这种写得不好的类型,我认为你的解决方案非常惯用。它不会人为地引入新的命名函数来执行初始化。而是保持初始化代码本地化。这在我的书中是件好事。