如果我有一个名为Tuple<T, SIZE>
的类,我想说,在编译库时会实例化20个不同的浮动模板(这样用户就不会遇到链接错误):
template Tuple<float, 1>;
template Tuple<float, 2>;
...
template Tuple<float, 20>;
有没有办法以递归方式执行上述操作?也许允许它是灵活的,这样我就可以把它放在我想要的任何数字上,并为我实例化这些类?
编辑:到目前为止我尝试了什么(似乎不起作用):
template <typename T, unsigned int MAX_RANGE>
class AllTuples
{
Tuple<T, MAX_RANGE> y;
AllTuples<T, MAX_RANGE - 1> x;
};
template <typename T>
class AllTuples<T, 1>
{
Tuple<T, 1> x;
};
AllTuples<float, 10>;
答案 0 :(得分:4)
对不起,你运气不好。除非您使用预处理器元编程库(boost.pp),否则无法自动执行此操作。不是模板元编程。
您生成的内容是Tuple<float, N>
的隐式实例化。但隐式实例化与显式实例化有两个重要区别
对于后者,由于我不知道原因,我只会引用该规范。
非导出模板必须在隐式实例化的每个翻译单元中定义(14.7.1),除非在某些翻译单元中明确实例化(14.7.2)相应的专业化;无需诊断。
这可能与链接器复杂性有关,因为同一模板的隐式实例化可能会在多个转换单元中多次出现,因此需要特殊处理。显式实例化和非内联函数不能。
答案 1 :(得分:1)
您可以使用一些模板魔法来强制实例化:
namespace {
template <unsigned N>
struct Instantiator {
void instantiate_members(const Tuple<float,N>& tuple, Instantiator<N-1>) {
// use **all** member functions here
// so that they get instantiated
}
template <>
struct Instantiator<0> {}
}
然后实例化此模板:
template class Instantiator<20>;
不幸的是,这在维护方面并不好,因为您需要使instantiate_members函数保持最新。并且您需要确保调用所有成员,包括所有各种重载。
答案 2 :(得分:0)
避免模板链接错误的正确方法是将模板定义放在您使用它们的每个TU中。通常头文件最适合此目的。使用像这样的显式实例化充其量只是半有效的,最糟糕的是该死的混乱。