【发布时间】:2012-06-27 21:11:46
【问题描述】:
我有两个模板结构,每个都包含一个 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);
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));
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;
};
main的输出是
TestStruct<d> 0
Dependency<d> 1.5
Dependency<f> 1.5
TestStruct<f> 1.5
也就是说,如果Dependency 已经为类型T 实例化,则TestStruct<T> 的staticVar 会被正确初始化,但否则它保持为0,因为Dependency<T>::staticVar 尚未初始化。取消注释 [1] 和 [2] 解决了类型 float 和 double 的问题(即,所有输出 1.5,即使已注释 [3]),但如果可能的话,我希望不必列出所有可能的类型或在不使用它们的代码中为这些类型实例化模板。我希望能够在TestStruct<T>(或testStruct.hpp)中添加一些内容,以保证Dependency 已为该类型实例化,而无需指定T 可能是什么类型。
我见过C++ Static member initalization (template fun inside) 和How to force a static member to be initialized?。第一个很好地解释了情况,但没有为像我这样的问题提出解决方案。第二个有两个解决方案,但似乎都不能在 GCC 4.2.1 中工作(或者我错误地应用了它......)。
还有其他我应该尝试的技巧或变通方法,还是我坚持显式实例化?
【问题讨论】:
-
This 是一本好书,可能会解决您的问题。
-
@cdhowie 用静态函数替换静态变量需要对接口进行(少量)更改,如果可能的话,我不希望这样做,因为存在使用这些结构的现有代码。不过,这可能是最好的选择。
-
升级编译器不行吗?
-
@surtur 是的,它确实改变了界面,这很糟糕。但它是唯一能让您明确控制何时构建事物的选项。
-
@user315052 不幸的是,它与需要支持旧编译器的遗留代码一起使用。
标签: c++ templates initialization static-members static-initialization