簡體   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. 我知道 static 初始化訂單慘敗,並發現了幾個關於該問題的討論,但沒有一個真正幫助我解決我的問題。 我什至不知道為什么這對我來說是個問題。

這是一個最小的例子,它重現了我從代碼中得到的錯誤:

#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;
}

使用 C++17 標准編譯完成,出現 0 個警告和 0 個錯誤。 但是,在執行程序時,調用Foo::insert時會發生分段錯誤。 看來Foo::map_在那一點上沒有初始化。 但是 static 變量不應該按照代碼中定義的順序進行初始化嗎?

我還應該提到,沒有模板的代碼可以正常工作。 所以我想知道編譯器是否以實際 class 定義在Bar之后的方式實例化模板。 可能是這樣的問題,還是編譯器在這種情況下恰好做了“正確”的事情?

static 模板特化的 static 數據成員的動態初始化(如果它們未顯式特化)與任何其他動態初始化完全無序(不確定排序)。 成員是否inline無關緊要,其他動態初始化是否也是 class 模板特化的 static 數據成員無關緊要,實例化點在哪里也無關緊要static 數據成員的定義和定義位於翻譯單元中。

因此,無法保證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:

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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM