2017-01-03 8 views
0

クラスFooがあり、テンプレート化された関数をいくつか持ち、それぞれのテンプレートをcppファイル内にA, B, Cという一連のインスタンスとしてインスタンス化したい場合は、 1つは、タイプを追加または削除したい場合はエラーが発生しやすく、毎回更新するのは面倒です。マクロトリックやメタプログラミング技術が役立つでしょうか?一連のテンプレート化された関数またはクラスをインスタンス化する便利なソリューション

ような何か:生成されます

//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); 
+0

とは全く異なるがありますすべてのインスタンス化は同じですか?なぜなら、もしあなたがそうであれば、それぞれのタイプについて宣言する必要はないからです。各タイプのテンプレートをインスタンス化するよりも便利な機能が必要な場合、実装は同じでなければなりません。 – Kerndog73

+0

実装はすべて同じですが、(私が間違っていれば私を修正してください)私はまだライブラリ/外部に使用するためにこのように宣言する必要があります。 – Brian

+0

する必要はありません。テンプレートがヘッダーファイルにある場合は、テンプレートが最初に使用されたときに、各タイプごとにインスタンス化されます。したがって、 'Foo :: add add 'は呼び出されたnomatterと呼ばれる最初にインスタンス化されます。 – Kerndog73

答えて

0

あなたはODR-使用あなたの機能をテンプレート可変引数ヘルパー関数を実行し、その機能をインスタンス化して、(あなたができると仮定するとのようなものあなたの型をデフォルトで構築します)。

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>({}, {})), ...); 
} 
0

技術が

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

ある

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

明示的にテンプレートをインスタンス化したいと仮定すると、これは専門

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 
関連する問題