Специализация по частичным методам 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 возможна частичная специализированная спецификация функций.