C++ 如何保证模板结构中常量静态成员的初始化顺序

C++ 如何保证模板结构中常量静态成员的初始化顺序,c++,templates,initialization,static-members,static-initialization,C++,Templates,Initialization,Static Members,Static Initialization,我有两个模板结构,每个都包含一个常量静态成员变量。这些成员变量之一的初始化取决于第二个变量。因此,我希望能够保证第二个在第一个之前初始化。下面是一个简化的示例: dependency.hpp: template<typename T, T> struct value { }; template <typename T> struct Dependency { Dependency() {} Dependency(T v) : var(v) {} const

我有两个模板结构,每个都包含一个常量静态成员变量。这些成员变量之一的初始化取决于第二个变量。因此,我希望能够保证第二个在第一个之前初始化。下面是一个简化的示例:

dependency.hpp:

template<typename T, T> struct value { };

template <typename T>
struct Dependency {
  Dependency() {}
  Dependency(T v) : var(v) {}
  const static Dependency staticVar;
  T var;
};

template <typename T>
const Dependency<T> Dependency<T>::staticVar = Dependency<T>(1.5);
模板结构值{};
模板
结构依赖{
依赖项(){}
依赖项(tv):var(v){}
const静态依赖staticVar;
T-var;
};
模板
const Dependency::staticVar=依赖关系(1.5);
testStruct.hpp:

#include "dependency.hpp"

//template class Dependency<double>; [1]
//template class Dependency<float>;  [2]

template <typename T>
struct TestStruct {
  TestStruct(Dependency<T> v) : var(v.var) {}

  const static TestStruct staticVar;
  T var;
};

template <typename T>
const TestStruct<T> TestStruct<T>::staticVar = TestStruct<T>(Dependency<T>(Dependency<T>::staticVar));
#包括“dependency.hpp”
//模板类依赖关系;[1]
//模板类依赖关系;[2]
模板
结构测试结构{
TestStruct(依赖项v):var(v.var){}
const static TestStruct staticVar;
T-var;
};
模板
const TestStruct TestStruct::staticVar=TestStruct(依赖项(依赖项::staticVar));
test.cpp:

#include <iostream>
#include "testStruct.hpp"

using namespace std;

int main(int argc, char *argv[])
{
  cout << "TestStruct<d> " << TestStruct<double>::staticVar.var << endl;
  cout << "Dependency<d> " << Dependency<double>::staticVar.var << endl;

  cout << endl;

  cout << "Dependency<f> " << Dependency<float>::staticVar.var << endl; // [3]
  cout << "TestStruct<f> " << TestStruct<float>::staticVar.var << endl;

  return 0;
};
#包括
#包括“testStruct.hpp”
使用名称空间std;
int main(int argc,char*argv[])
{

cout正如cdhowie所建议的,您可以使用静态方法来确保
TestStruct
Dependency
之间的初始化顺序。如果您真正关心的是维护静态变量而不是静态方法的外观,那么可以使用静态方法调用初始化的静态引用变量

您只需要确保静态方法实现本身不使用静态引用变量,以便在全局初始化上下文中安全地调用它们

template <typename T>
struct Dependency {
  Dependency() {}
  Dependency(T v) : var(v) {}
  static const Dependency & staticMethod () {
      static const Dependency staticMethodVar(1.5);
      return staticMethodVar;
  }
  static const Dependency & staticVar;
  T var;
};

template <typename T>
const Dependency<T> & Dependency<T>::staticVar
        = Dependency<T>::staticMethod();

template <typename T>
struct TestStruct {
  TestStruct(Dependency<T> v) : var(v.var) {}
  static const TestStruct & staticMethod () {
      static const TestStruct staticMethodVar(Dependency<T>::staticMethod());
      return staticMethodVar;
  }
  static const TestStruct & staticVar;
  T var;
};

template <typename T>
const TestStruct<T> & TestStruct<T>::staticVar
        = TestStruct<T>::staticMethod();
模板
结构依赖{
依赖项(){}
依赖项(tv):var(v){}
静态常量依赖项和静态方法(){
静态常量依赖关系staticMethodVar(1.5);
返回staticMethodVar;
}
静态常量依赖关系&staticVar;
T-var;
};
模板
常量依赖项和依赖项::staticVar
=依赖项::staticMethod();
模板
结构测试结构{
TestStruct(依赖项v):var(v.var){}
static const TestStruct和staticMethod(){
静态常量TestStruct staticMethodVar(Dependency::staticMethod());
返回staticMethodVar;
}
静态常量TestStruct&staticVar;
T-var;
};
模板
常量TestStruct&TestStruct::staticVar
=TestStruct::staticMethod();

是一本很好的读物,可能会解决您的问题。@cdhowie用静态函数替换静态变量需要(次要)对接口进行更改,如果可能的话,我不希望这样做,因为现有的代码使用这些结构。不过这可能是最好的选择。升级编译器是不可能的吗?@surtur是的,它确实会更改接口,这很糟糕。但这是唯一一个可以让您显式控制何时出现问题的选项结构化。@user315052不幸的是,这用于需要支持旧编译器的旧代码。
template <typename T>
struct Dependency {
  Dependency() {}
  Dependency(T v) : var(v) {}
  static const Dependency & staticMethod () {
      static const Dependency staticMethodVar(1.5);
      return staticMethodVar;
  }
  static const Dependency & staticVar;
  T var;
};

template <typename T>
const Dependency<T> & Dependency<T>::staticVar
        = Dependency<T>::staticMethod();

template <typename T>
struct TestStruct {
  TestStruct(Dependency<T> v) : var(v.var) {}
  static const TestStruct & staticMethod () {
      static const TestStruct staticMethodVar(Dependency<T>::staticMethod());
      return staticMethodVar;
  }
  static const TestStruct & staticVar;
  T var;
};

template <typename T>
const TestStruct<T> & TestStruct<T>::staticVar
        = TestStruct<T>::staticMethod();