Для начала у вас есть пара проблем syntacti c в вашем коде. Кроме того, вам не нужно Method
, чтобы вообще быть аргументом шаблона, поскольку вы всегда хотите передать функцию-член типа Object
.
Чтобы получить переменное число аргументов в callMethod
, просто предоставьте пакет параметров c variadi для Foo
. Кроме того, вы можете определить тип возврата функции callMethod
.
Собрав все это вместе, вы можете получить:
template <typename Obj, typename Ret, typename ...Args>
class Foo
{
public:
Foo(Obj *obj, Ret (Obj::*method)(Args...))
: mObj(obj), mMethod(method)
{}
Ret callMethod(Args... args)
{
return (mObj->*mMethod)(args...);
}
private:
Obj* mObj;
Ret (Obj::*mMethod)(Args...); // this is essentially 'Method'
};
Теперь, если у вас есть классы с переменным числом аргументов для Для конкретной функции она работает нормально:
class Bar
{
public:
void method() { std::cout << "bar"; }
};
class Car
{
public:
int method2(int, double) {
std::cout << "car";
return 42;
}
};
int main()
{
Bar bar;
Car car;
Foo a (&bar, &Bar::method);
Foo b (&car, &Car::method2);
a.callMethod(); // prints 'bar'
b.callMethod(5, 3.2); // prints 'car'
}
Вот рабочая демоверсия .
Обратите внимание, что в реальном решении вы, вероятно, захотите совершить пересылку аргументов , но это должно привести вас на правильный путь.
Кроме того, до c ++ 17 нет CTAD (вычитание аргумента шаблона класса), поэтому вы должны указать аргументы шаблона при построении Foo
объекты, как это:
Foo <Bar, void> a(&bar, &Bar::method);
Foo <Car, int, int, double> b(&car, &Car::method2);