5

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と実装ファイルの明示的なクラステンプレートのインスタンス化の間には、コードの重複があります。通常のようにヘッダーファイルに「すべて」を入れる必要のない重複を取り除く方法はありますか?

4

3 に答える 3

3

精巧な型指定子でtypedef名が使用されているため、これは無効であり、実装によって拒否されます

template class addition;

以下も無効です。これは、標準では、精巧な型指定子に単純なテンプレートIDが含まれている必要があると規定されているためです。ただし、Comeauonlineと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ファイルを作成するのか、すべてヘッダーファイルまたはcppファイルの内容を保持する「.icc」などの個別のファイルに含める必要があるのか​​と自問します。よくわかりませんが、tempalatesの定義は常にコンパイル単位にあるべきではありません。

-> C++テンプレート関数定義の.CPPファイルへの保存を参照してください。

于 2012-11-11T14:56:50.500 に答える