1

这是我的问题的简化形式(基于一个真实的库):

// class template with static member variable:
template <typename T>
struct X 
{
  static std::vector<T> v_;
};

// definition of that static member variable:
template <typename T>
std::vector<T> X<T>::v_{};

// explicit instantiation of the class template:
template struct X<int>;

// library initialization function that fills v_ for X<int>:
static bool init()
{
  X<int>::v_.reserve(1000);
  ...
  return true;
}

// automatic initialization:
static bool initialized = init();

我的问题是,在这种情况下(单个翻译单元)是否可以保证——按照定义和实例化的顺序——在函数被调用X<int>::v_之前被初始化。init()


AFAIK,静态变量按其定义的顺序在单个翻译单元中初始化,但是模板和显式实例化可以改变它吗?如果那个显式实例化被移除了怎么办?或者,放在源代码的末尾?

4

1 回答 1

2

[basic.start.dynamic]

如果变量是隐式或显式实例化的特化,则具有静态存储持续时间的非局部变量的动态初始化是无序的,如果变量是不是隐式或显式实例化的特化的内联变量,则它是部分排序的,否则是有序的.

[注 1:显式特化的非内联静态数据成员或变量模板特化已排序初始化。——尾注]

正如标准所指出的,的初始化v_无序的。

但我们总是可以通过static函数来​​解决这个问题:

template<typename T>
struct X{
    static std::vector<T>& v_() noexcept {
        static std::vector<T> v;
        return v;
    }
};
template struct X<int>;
static bool init(){
    X<int>::v_().reserve(1000);
    // ...
    return true;
}
static bool initialized = init();
于 2020-10-30T14:18:30.123 回答