К сожалению, текущий C ++ требует от вас написания набора шаблонов различной длины, по одному для каждого возможного количества аргументов.В принципе, C ++ 0x позволит вам использовать шаблоны с переменными числами, например, так:
template<typename Rv, typename Wrapper, typename... Args>
struct impl_wrapper {
std::function<Rv (Args...)> func;
Rv operator()(Args... args) const {
Wrapper w;
return func(args...);
}
impl_wrapper(const std::function<Rv (Args...)> f)
: func(f)
{
}
};
template<typename Wrapper>
struct wrap_func_ {
template<typename Rv, typename... Args>
impl_wrapper<Rv, Args...> operator()(const std::function<Rv (Args...)> &f)
{
return impl_wrapper<Rv, Wrapper, Args...>(f);
}
};
template<typename Wrapper>
static wrap_func_<Wrapper> wrap_func;
struct test_wrapper {
test_wrapper() {
std::cout << "Begin call!\n";
}
~test_wrapper() {
std::cout << "End call!\n";
}
};
int test_call(int x, char *y) {
std::cout << y << x << std::endl;
return x + 1;
}
int main() {
std::function<int (int, char *)> f = test_call;
f = wrap_func<test_wrapper>(f);
std::cout << "Returned: " << f(42, "Prior to increment: ") << std::endl;
return 0;
}
Однако это требует поддержки функций, еще не реализованных в G ++, и, скорее всего, в любом другом существующем компиляторе C ++:
test.cpp:21: sorry, unimplemented: cannot expand ‘Args ...’ into a fixed-length argument list
Следовательно, вместо каждого допустимого количества аргументов вы должны использовать перегрузку шаблона, вплоть до некоторого разумного максимума.