2017-01-03 11 views
0

Если у меня был класс Foo, с несколькими шаблонами функций и хотелось бы создать экземпляр для ряда других типов A, B, C в своем файле cpp, в настоящее время мне приходится писать каждый один, это может быть подвержено ошибкам, если я хочу добавить или удалить тип, и это просто раздражает, чтобы обновлять каждый раз. Есть ли какие-либо макро-трюки или методы метапрограммирования, которые могли бы помочь?Удобные решения для создания последовательности шаблонных функций или классов

Что-то вроде:

//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

Are реализации всех экземпляры одинаковы? Потому что, если они вам не нужно объявлять их для каждого типа. Если вы хотите функцию удобства, чем создает экземпляр шаблона для каждого типа, то реализации должны быть одинаковыми. – Kerndog73

+0

Реализации все одинаковы, но (исправьте меня, если я ошибаюсь) Мне все равно нужно объявить их таким образом, чтобы они использовались для библиотеки/извне. – Brian

+0

Вам не нужно. Если шаблон находится в файле заголовка, он будет создан для каждого типа при первом использовании. Таким образом, 'Foo :: add ' будет создан при первом вызове имени, где он называется. – Kerndog73

ответ

0

Вы можете сделать шаблон VARIADIC вспомогательную функцию с УСО используемых вашими функциями и экземпляр этой функции, что-то вроде (предполагается, что вы можете по умолчанию создайте свои типы,)

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