【问题标题】:Convenient solutions to instantiate a series of templated functions or classes实例化一系列模板化函数或类的便捷解决方案
【发布时间】:2017-01-03 07:25:00
【问题描述】:

如果我有 Foo 类,带有一些模板函数,并且想在其 cpp 文件中为一系列其他类型 A, B, C 实例化每个函数,我目前必须编写每个函数,这可能容易出错如果我想添加或删除一个类型,每次更新都很烦人。是否有任何宏技巧或元编程技术可以提供帮助?

类似:

//Foo cpp
template <typename T>
T Foo::add(T t0, T 01) {
    return t0 + t1;
}

INSTANTIATE_TEMPLATE(Foo::add, A, B, C)

会生成:

template A Foo::add<A>(A t0, A t1);
template B Foo::add<B>(B t0, B t1);
template C Foo::add<C>(C t0, C t1);

【问题讨论】:

  • 所有实例化的实现都一样吗?因为如果它们是你不需要为每种类型声明它们。如果您想要一个方便的函数而不是为每种类型实例化模板,那么实现必须相同。
  • 实现都是一样的,但是(如果我错了,请纠正我)我仍然需要以这种方式声明它们以用于库/外部。
  • 你不需要。如果模板在头文件中,那么它将在第一次使用时为每种类型实例化。所以Foo::add &lt;A&gt; 将在第一次被调用时被实例化。
  • 但是我需要在编译后调用这些函数,我实际上并没有在我的 c++ 代码中使用它们,所以它们永远不会被隐式实例化。所以我需要明确地实例化它们。
  • 如果模板是在头文件中实现的,那么正在编译包含您的头文件的文件的“其他编译器”将隐式地使模板实例化。如果模板的实现在 cpp 文件中,则“其他编译器”无法访问它,因此无法隐式实例化它。

标签: c++ macros metaprogramming


【解决方案1】:

假设你想显式实例化你的模板

template <typename T>
T Foo::add(T t0, T t1) {return t0 + t1;}

技术是

int Foo::add<int>(int, int);    // instantiate for T = int
double Foo::add<double>(double, double);    // instantiate for T = double

这和专业化完全不同

template<> std::string Foo::add<std::string>(std::string x, std::string y)
   {return y+x;};
    // assume we want add<std::string>() to append the first string to the second,
    //  not the second string to the first

【讨论】:

    【解决方案2】:

    您可以使用 odr-used 您的函数执行模板可变参数辅助函数并实例化该函数,例如(假设您可以默认构造您的类型,)

    template <typename ... Ts>
    void add_instantiator(Foo& foo)
    {
        int dummy[] = {0, (static_cast<void>(foo.add<Ts>({}, {})), 0)...};
        static_cast<void>(dummy); // Avoid warning for unused variable
    }
    
    template void add_instantiator<A, B, C>(Foo&);
    

    或者在 C++17 中使用折叠表达式:

    template <typename ... Ts>
    void add_instantiator(Foo& foo)
    {
        (static_cast<void>(foo.add<Ts>({}, {})), ...);
    }
    

    【讨论】:

      猜你喜欢
      • 2018-05-31
      • 1970-01-01
      • 1970-01-01
      • 2019-09-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-02-09
      • 1970-01-01
      相关资源
      最近更新 更多