C ++ 0x добавляет переменные шаблоны, которые напрямую поддерживают шаблон, который принимает произвольное количество параметров.Без этого вы можете использовать частичную специализацию для симуляции, хотя она требует отдельной специализации для каждого числа параметров.Например, вы можете поддерживать от 1 до 3 параметров, таких как:
class null_class {};
template <class func, class arg1, class arg2, class arg3>
class callback_t {
func f;
arg1 a;
arg2 b;
arg3 c;
public:
callback_t(func f, arg1 a, arg2 b, arg3 c) : f(f), a(a), b(b), c(c) {}
double operator()() const { return f(a, b, c); }
};
template <class func, class arg1, class arg2>
class callback_t<func, arg1, arg2, null_class> {
func f;
arg1 a;
arg2 b;
public:
callback_t(func f, arg1 a, arg2 b) : f(f), a(a), b(b) {}
double operator()() const { return f(a, b); }
};
template <class func, class arg1>
class callback_t<func, arg1, null_class, null_class> {
func f;
arg1 a;
public:
callback_t(func f, arg1 a) : f(f), a(a) {}
double operator()() const { return f(a); }
};
template <class func, class arg1, class arg2, class arg3>
callback_t<func, arg1, arg2, arg3>
callback(func f, arg1 a, arg2 b, arg3 c) {
return callback_t<func, arg1, arg2, arg3>(f, a, b, c);
}
template <class func, class arg1, class arg2>
callback_t<func, arg1, arg2, null_class>
callback(func f, arg1 a, arg2 b) {
return callback_t<func, arg1, arg2, null_class>(f, a, b);
}
template <class func, class arg>
callback_t<func, arg, null_class, null_class>
callback(func f, arg a) {
return callback_t<func, arg, null_class, null_class>(f, a);
}
#ifdef TEST
#include <iostream>
double square(double d) {
return d * d;
}
double add(double a, double b) {
return a + b;
}
double sum(double a, double b, double c) {
return a + b + c;
}
int main() {
double a = 2.0, b = 3.0, c=4.0;
double d = callback(square, a)();
double e = callback(add, b, c)();
double f = callback(sum, a, b, c)();
std::cout << "2.0 squared = " << d << "\n";
std::cout << "3.0 + 4.0 = " << e << "\n";
std::cout << "Sum = " << f << "\n";
return 0;
}
#endif
Тип возвращаемого значения также может быть шаблонным, но я оставил это для простоты (или, по крайней мере, для уменьшения сложности).