специализация шаблона для целого набора параметров

#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> { ... };