C ++: частичная специализация шаблонных классов шаблонов - PullRequest
8 голосов
/ 04 января 2012

следующий код:

using namespace std;

template <typename X>
class Goo {};


template <typename X>
class Hoo {};


template <class A, template <typename> class B = Goo >
struct Foo {
  B<A> data;
  void foo1();
  void foo2();

};


template <typename A>
void Foo<A>::foo1() { cout << "foo1 for Goo" << endl;}


int main() {
  Foo<int> a;
  a.foo1();

}

выдает ошибку компилятора:

test.cc:18: error: invalid use of incomplete type 'struct Foo<A, Goo>'
test.cc:11: error: declaration of 'struct Foo<A, Goo>'

Почему я не могу частично специализировать foo1 ()? Если это не так, как мне это сделать?

У меня другой вопрос: что если я хочу, чтобы foo2 () определялась только для A = int, B = Hoo а не для какой-либо другой комбинации, как мне это сделать?

Ответы [ 2 ]

5 голосов
/ 04 января 2012

Шаблоны функций могут быть только полностью специализированными, но не частично.

Функции-члены шаблонов классов автоматически являются шаблонами функций, и они действительно могут быть специализированными, но только полностью:

template <>
void Foo<int, Goo>::foo1() { }  // OK

Вы можете частично специализировать весь класс и затем определить его заново:

template <typename A>
struct Foo<A, Goo>
{
  // ...
};

(подробности см. В 14.7.3.)

1 голос
/ 04 января 2012

В шаблоне по-прежнему есть два параметра, и вы должны написать что-то вроде этого:

template <typename A, template <typename> class B>
void Foo<A,B>::foo1() { cout << "foo1" << endl;}

Значение по умолчанию указано, и его нужно указать только один раз.С тех пор, это как любой другой шаблон с двумя параметрами.Этот код будет применяться независимо от того, что B (по умолчанию или иным образом).Если затем вы хотите указать другое поведение для определенного B, , тогда вы делаете специализацию класса, а не только метода.

( Сильно отредактировано )

...