实例化多个模板

时间:2011-06-18 17:26:34

标签: c++ templates

如果我有一个名为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>;

3 个答案:

答案 0 :(得分:4)

对不起,你运气不好。除非您使用预处理器元编程库(boost.pp),否则无法自动执行此操作。不是模板元编程。

您生成的内容是Tuple<float, N>隐式实例化。但隐式实例化与显式实例化有两个重要区别

  1. 他们不会实例化所有成员定义(仅实例化那些立即需要的成员定义)。其他定义仅在使用时进行实例化。
  2. 使用的成员定义的隐式实例化不能用作其他翻译单元的定义源。
  3. 对于后者,由于我不知道原因,我只会引用该规范。

      

    非导出模板必须在隐式实例化的每个翻译单元中定义(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中。通常头文件最适合此目的。使用像这样的显式实例化充其量只是半有效的,最糟糕的是该死的混乱。