tree.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;
// ...
tree.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与实现文件中的显式类模板实例之间存在一些代码重复。有没有办法摆脱不需要像往常一样在头文件中放入“所有内容”的复制?
答案 0 :(得分: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"
答案 1 :(得分:1)
这是无效的并且被实现拒绝,因为在详细类型说明符中使用了typedef名称
template class addition;
以下内容也是无效的,因为标准规定必须在详细的类型说明符中包含一个简单的模板ID。但Comeau在线和海湾合作委员会都接受了。
template class addition::binary_operation;
您可以应用变态解决方法,但要完全符合标准
template<typename T> using alias = T;
template class alias<multiplication>::binary_operation;
至少我不能再快速浏览一下规格就无效了。
答案 2 :(得分:0)
我问自己,为什么你实际上写了一个.cpp文件,因为你有模板,他们应该全部在头文件或seprarate文件中,例如“.icc”,它保存来自cpp文件的东西。我不确定,但是定义应该始终不在编译单元中。
参见 - &gt; Storing C++ template function definitions in a .CPP file