Перегрузка классов шаблонов по номеру шаблона шаблона
Возможно ли иметь несколько версий одного и того же класса, которые отличаются только количеством принимаемых им шаблонных аргументов?
Например:
template<typename T>
class Blah {
public:
void operator()(T);
};
template<typename T, typename T2>
class Blah {
public:
void operator()(T, T2);
};
Я пытаюсь моделировать объекты типа functor, которые могут принимать переменное количество аргументов (вплоть до количества различных выписанных шаблонов).
Ответы
Ответ 1
Самый простой ответ - иметь только один шаблон с максимальным числом, которое вы хотите поддерживать, и использовать void для типа по умолчанию для всех, кроме первого типа. Затем вы можете использовать частичную специализацию по мере необходимости:
template<typename T1, typename T2=void>
struct foo {
void operator()(T1, T2);
};
template <typename T1>
struct foo<T1, void> {
void operator()(T1);
};
int main() {
foo<int> test1;
foo<int,int> test2;
test1(0);
test2(1,1);
}
Ответ 2
Шаблон может иметь только одно базовое определение. Если вам нужно переменное количество аргументов, и вы не хотите использовать конструкции "нулевого типа", как предлагает @awoodland, и если у вас есть компилятор С++ 0x, вы можете использовать вариативные шаблоны:
template <typename ...Dummy> struct foo; // base case, never instantiated!
template <typename T> struct foo<T> { /*...*/ }; // partial spec. for one parameter
template <typename T, typename U> struct foo<T, U> { /*...*/ }; // ditto for two
Ответ 3
Это непроверенный код, у меня нет версии boost, но здесь все равно
#include "boost/tuple.h"
template <class T>
class Blah;
template <class T>
class Blah< boost::tuple<T> >
{
void operator()(T arg);
};
template <class T, class U>
class Blah< boost::tuple<T, U> >
{
void operator()(T arg1, U arg2);
};
и т.д.. и др.