2017-01-03 70 views
0

如果我有Foo類,帶有一些模板化函數,並且想要在其cpp文件中爲其他類型的其他類型A, B, C實例化,我目前必須寫每個其一,如果我想添加或移除一個類型,這可能會出錯,並且每次更新都會很煩人。是否有任何宏伎倆或元編程技術可以幫助?實例化一系列模板化函數或類的方便解決方案

喜歡的東西:

//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 '將在第一次被稱爲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

假設你想顯式實例模板

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

的技術是

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

這是從專業化

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