5

树.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 与实现文件中的显式类模板实例化之间存在一些代码重复。有什么方法可以摆脱不需要像往常一样将“所有内容”放在头文件中的重复项?

4

3 回答 3

3

这是无效的并且被实现拒绝,因为在详细类型说明符中使用了 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;

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

于 2012-11-11T15:50:38.763 回答
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"
于 2012-11-11T15:22:13.327 回答
0

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

请参阅 ->在 .CPP 文件中存储 C++ 模板函数定义

于 2012-11-11T14:56:50.500 回答