#c #templates
#c #шаблоны
Вопрос:
Возможно, это легко решить, но трудно найти решение для этого:
Возможно ли (частично) специализироваться для целого набора типов? В примере «Foo» должен быть частично специализирован для (T,int) и (T,double) только с одним определением шаблона.
Что я могу сделать, так это определить специализацию для (T,int). Смотрите ниже. Но это должно быть для (T, int) и (T,double) только с одним определением функции (без дублирования кода).
template <typename T,typename T2>
struct Foo
{
static inline void apply(T a, T2 b)
{
cout << "we are in the generic template definition" << endl;
}
};
// partial (T,*)
template <typename T>
struct Foo<T, int > // here something needed like T2=(int, double)
{
static inline void apply(T a, T2 b)
{
cout << "we are in the partial specialisation for (T,int)" << endl;
}
};
Есть идеи, как частично специализировать это для (T, int) и (T, double) с одним определением шаблона?
Комментарии:
1. Как компилятор мог узнать, что здесь делать? Как он узнает, что вы хотите распечатать
"partial double"
и т.д.?2. Вывод предназначен только для того, чтобы узнать, какое определение функции использовалось.
Ответ №1:
Если я правильно понял ваш вопрос, то вы можете написать шаблон базового класса и на его основе производить, как показано ниже:
template <typename T, typename U>
struct Foo_Base
{
static inline void apply(T a)
{
cout << "we are in the partial specialisation Foo_Base(T)" << endl;
}
};
template <typename T>
struct Foo<T, int> : Foo_Base<T, int> {};
template <typename T>
struct Foo<T, double> : Foo_Base<T, double> {};
Хотя это не одно определение шаблона (как вы просили), но вы можете избежать дублирования кода.
Демонстрация:http://www.ideone.com/s4anA
Комментарии:
1. Спасибо за ответ. К сожалению, вы использовали обстоятельство, которое было применено в исходном вопросе, который не был предназначен таким образом. «Оба» типа необходимы в качестве параметра функции. Извините, я не был конкретен в этом.
2. @Frank: Теперь смотрите мой ответ. Теперь
Foo_Base
ожидается два аргумента типа, и поэтому я передаю их при выводе из него3. Отличная идея! Вы правы. Это не одно определение, но позволяет избежать удвоения кода. В данном случае это работает.
Ответ №2:
Я полагаю, вы могли бы сделать это, используя enable_if от Boost, чтобы включить частичную специализацию только для тех типов, которые вы хотите. В разделе 3.1 показано, как это делается, и приводится этот пример:
template <class T, class Enable = void>
class A { ... };
template <class T>
class A<T, typename enable_if<is_integral<T> >::type> { ... };