【问题标题】:Code duplication between typedefs and explicit instantiationstypedef 和显式实例化之间的代码重复
【发布时间】:2012-07-10 13:50:53
【问题描述】:

树.h

template<typename Functor, char Operator>
class binary_operation : public node
{
// ... unimportant details ...

    unsigned evaluate() const;
    void print(std::ostream& os) const;
};

typedef binary_operation<std::plus<unsigned>, '+'> addition;
typedef binary_operation<std::multiplies<unsigned>, '*'> multiplication;
// ...

树.cpp

template<typename Functor, char Operator>
unsigned binary_operation<Functor, Operator>::evaluate() const
{
    // ... unimportant details ...
}

template<typename Functor, char Operator>
void binary_operation<Functor, Operator>::print(std::ostream& os) const
{
    // ... unimportant details ...
}

template class binary_operation<std::plus<unsigned>, '+'>;
template class binary_operation<std::multiplies<unsigned>, '*'>;
// ...

如您所见,头文件中的 typedef 与实现文件中的显式类模板实例化之间存在一些代码重复。有什么方法可以摆脱不需要像往常一样将“所有内容”放在头文件中的重复项?

【问题讨论】:

  • 我认为你不能在 .cpp 文件中写 template class addition;,这是一种耻辱。
  • 不 :( error: using typedef-name 'addition' after 'class'
  • 我认为 decltype 也无济于事......但 C++ 仍然有旧的预处理器......你可以用公共部分制作一个宏 :-)
  • 您可以添加第二个头文件,并将代码放在那里。没有多大帮助,但它会防止你的原始 .h...

标签: c++ templates typedef header-files code-duplication


【解决方案1】:

这是无效的并被实现拒绝,因为在详细类型说明符中使用了 typedef 名称

template class addition;

以下内容也是无效的,因为标准规定在详细类型说明符中必须包含一个简单的模板 id。不过,Comeau online 和 GCC 都接受它。

template class addition::binary_operation;

您可以应用变态的变通方法以完全符合标准

template<typename T> using alias = T;
template class alias<multiplication>::binary_operation;

至少我在快速浏览规范时不再发现它是无效的。

【讨论】:

    【解决方案2】:

    使用宏。你可以写一个像

    这样的标题
    I_HATE_MACROS(binary_operation<std::plus<unsigned>, '+'>, addition)
    I_HATE_MACROS(binary_operation<std::multiplies<unsigned>, '*'>, multiplication)
    

    那你就可以了

    #define I_HATE_MACROS(a, b) typedef a b;
    

    或者

    #define I_HATE_MACROS(a, b) template class a;
    

    然后

    #include "DisgustingMacroHackery.h"
    

    【讨论】:

    • 快速说明:由于 I_HATE_MACROS 中第一个参数中的逗号,这并不完全有效。为了使其工作,它需要与stackoverflow.com/a/13842612/543913 之类的东西结合使用
    【解决方案3】:

    我问我自己,你为什么要写一个 .cpp 文件,因为你有模板,它们应该全部放在头文件或单独的文件中,例如“.icc”,其中包含 cpp 文件中的内容.我不确定,但模板定义不应始终位于编译单元中。

    见->Storing C++ template function definitions in a .CPP file

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-08-25
      • 1970-01-01
      • 1970-01-01
      • 2020-04-09
      • 2020-09-11
      • 1970-01-01
      • 2015-04-07
      • 1970-01-01
      相关资源
      最近更新 更多