Специализация по частичным методам C++

Есть ли частичная специализация метода класса шаблона?

 template <class A, class B>
 class C
 {
  void foo();
 }

он не работает, чтобы специализироваться на этом следующим образом:

template <class A> void C<A, CObject>::foo() {};

Любая помощь?

Ответ 1

Если у вас уже есть специализированный класс, вы можете дать различную реализацию foo в специализированном классе:

template<typename A, typename B>
class C
{
public:
    void foo() { cout << "default" << endl; };
};

template<typename A>
class C<A, CObject>
{
public:
  void foo() { cout << "CObject" << endl; };
};

Чтобы специализировать функцию-член в Visual С++ 2008, вы также можете создать шаблон:

template<typename A, typename B>
class C
{
  template<typename T>
  void foo();

  template<>
  void foo<CObject>();
};

Решение выше, похоже, будет доступно только в будущем С++ Standard (согласно проекту n2914 14.6.5.3/2).

Ответ 2

Я думаю, что есть недоразумение.

Существует два типа шаблонов:

  • классы шаблонов
  • методы шаблона

В вашем примере у вас есть класс шаблонов, который, конечно, содержит некоторые методы. В этом случае вам придется специализироваться на классе.

template <class A>
class C<A,CObject>
{
  void foo() { ... } // specialized code
};

Проблема в вашем примере относительно проста: вы определите метод foo для специализации C, но эта специализация никогда не была объявлена ​​ заранее.

Проблема заключается в том, что вам нужно полностью специализировать свой класс C (и, таким образом, копировать большое количество данных). Существует несколько способов обхода.

  • Наследование (состав?): выполните всю общую работу в базовом классе, затем наследуйте класс C и специализируйтесь
  • Друг: вместо того, чтобы метод foo был членом C, определите его как дружественные свободные функции и специализируйте только этот метод
  • Делегирование: попросите свой метод "foo" вызвать другой метод "bar", который является свободной функцией и соответствующим образом "бар"

Что в коде дает:

// 1- Inheritance
template <class A, class B>
class CBase
{
  // Everything that does not require specialization
};

template <class A, class B>
class C: public CBase<A,B>
         // depending on your need, consider using another inheritance
         // or even better, composition
{
  void foo(); // generic
};

template <class A>
class C<A,CObject> : public CBase<A,CObject>
{
  void foo(); // specialized
};

// 2- Friend
// note the change in signature:
// - now you need to pass the attributes to be changed
// - the last parameter helps differentiating the overload
//   as there is no specialization for functions
template <class A, class B> void foo(Arg1&, Arg2&, const B&);
template <class A> void foo(Arg1&, Arg2&, const CObject&);

template <class A, class B>
class C
{
  friend template <class, class> foo;
};

// 3- Delegation
// same signature as foo in (2)
template <class A, class B> void bar(Arg1&, Arg2&, const B&);
template <class A> void bar(Arg1&, Arg2&, const CObject&);

template <class A, class B>
class C
{
  void foo() { bar(member1, member2, B()); }
};

Надеюсь, он прояснит и поможет!

Ответ 3

Нет, в С++ 0x не добавляется специализированная спецификация шаблонов функций.

Как правильно сказано выше, в отношении шаблонов функций в основном было выполнено 2 вещи:

  • аргументы шаблона по умолчанию были доступны;
  • были введены вариативные шаблоны.

Итак, как и раньше, обходные пути следует использовать для "эмулирования" специализированных специализированных шаблонов функций.

Ответ 4

Так как класс является шаблоном, вам необходимо специализироваться на том, что:

template <class A>
class C<A, CObject> 
{
   void foo() { ... }
}

Ответ 5

Если я правильно помню, вы не можете выполнять частичную специализацию шаблонов для функций. Не уверен, включен ли он в С++ 0X

Update: (Ожидание подтверждения) Как отмечено в комментариях, в С++ 0X возможна частичная специализированная спецификация функций.