简体   繁体   English

class模板中static内联成员变量的初始化顺序(C++17)

[英]Initialization order of static inline member variables in class templates (C++17)

I am working on a code where I need a static member variable of some class to be initialized using a static variable of an instance of a class template. I am working on a code where I need a static member variable of some class to be initialized using a static variable of an instance of a class template. I know about the static initialization order fiasco and found several discussions on that issue but none of them really helped me with my problem.我知道 static 初始化订单惨败,并发现了几个关于该问题的讨论,但没有一个真正帮助我解决我的问题。 I don't even know why that should be a problem in my case.我什至不知道为什么这对我来说是个问题。

This is a minimal example that reproduces the error I get from my code:这是一个最小的例子,它重现了我从代码中得到的错误:

#include <string>
#include <map>


template<class T>
class Foo {

private:

    static inline std::map<std::string, T> map_ = {};
    
public:
    
    static bool insert(const std::string& key, T value) {

        map_[key] = value;
        return true;
    }
};


using MyFoo = Foo<char>;

class Bar {
    static inline bool baz_ = MyFoo::insert("baz", 'A');
};


int main() {
    // This works just fine if the definition of Bar::baz_ in line 24 is removed
    //MyFoo::insert("baz", 'A');
    return 0;
}

Compilation using the C++17 standard finishes with 0 warnings and 0 errors.使用 C++17 标准编译完成,出现 0 个警告和 0 个错误。 When the program is executed, however, a segmentation fault occurs when Foo::insert is called.但是,在执行程序时,调用Foo::insert时会发生分段错误。 It appears that Foo::map_ is not initialized at that point.看来Foo::map_在那一点上没有初始化。 But shouldn't the static variables be initialized in the same order as they are defined in the code?但是 static 变量不应该按照代码中定义的顺序进行初始化吗?

I should also mention that the code without the template works fine.我还应该提到,没有模板的代码可以正常工作。 So I am wondering if the compiler instantiates the template in a way that the the actual class is defined after Bar .所以我想知道编译器是否以实际 class 定义在Bar之后的方式实例化模板。 Could something like that be the problem or does the compiler just happen to do the 'right' thing in that case?可能是这样的问题,还是编译器在这种情况下恰好做了“正确”的事情?

Dynamic initialization of static data members of class template specializations (if they are not explicitly specialized) are completely unordered (indeterminately-sequenced) with any other dynamic initialization. static 模板特化的 static 数据成员的动态初始化(如果它们未显式特化)与任何其他动态初始化完全无序(不确定排序)。 It doesn't matter whether the member is inline or not, it doesn't matter whether the other dynamic initialization is also of a static data member of a class template specialization or not, and it also doesn't matter where the points of instantiation and definition of the static data member are located in the translation unit.成员是否inline无关紧要,其他动态初始化是否也是 class 模板特化的 static 数据成员无关紧要,实例化点在哪里也无关紧要static 数据成员的定义和定义位于翻译单元中。

Therefore there is no way to guarantee that Foo<char>::map_ is initialized before Bar::baz_ .因此,无法保证Foo<char>::map_Bar::baz_之前初始化。

Instead use the common idiom of using a static member function containing the static member as a local static variable instead: Instead use the common idiom of using a static member function containing the static member as a local static variable instead:

static auto& map_() {
    static std::map<std::string, T> map = {};
    return map;
}

// replace `map_` with `map_()` everywhere else

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 C++17 内联成员可以强制跨 TU 的全局变量的初始化顺序吗? - Can initialization order of global variables across TUs be forced with C++17 inline members? 默认情况下,C ++ 17中的模板是否内联静态变量? - Are static variables inlined by default inside templates in C++17? Class type undefined in static member lambda function in C++17 - Class type undefined in static member lambda function in C++17 为什么C ++ 17中的全局内联变量和静态内联成员需要保护? - Why do global inline variables and static inline members in C++17 need guards? C++17 中的静态 constexpr 和静态内联变量有什么区别? - What's the difference between static constexpr and static inline variables in C++17? 使用 C++17 检测 class 成员是否存在 - Detecting if a class member exists with C++17 C++17 内联变量 vs 内联 static 变量 - C++17 inline variable vs inline static variable 在 C++17 中初始化后可以更改内联变量吗? - Can an inline variable be changed after initialization in C++17? C++17 中不可复制变量的成员初始化 - Member initialization for non-copyable variable in C++17 内联初始化 static const class 成员的初始化顺序保证 - Initialization order guarantees for inline-initialized static const class member
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM