Как передать метод и вызвать его с переменным количеством аргументов
у меня урок
CallProtector
это должно вызывать метод с переменным количеством аргументов, которые предполагают защиту вызова через мьютекс, но я не могу понять, как передать метод объекта с их аргументами. Вот что у меня есть до сих пор:
class CallProtector
{
public:
template<typename F, typename ...Args>
void callProtectedMethod(F& lambda, Args... args)
{
std::lock_guard<std::mutex> guard(m_guard);
lambda(args);
}
private:
std::mutex m_guard;
};
Я пытаюсь использовать это следующим образом:
class Car
{
public:
void updateEngine(int engineModelType) {}
};
int main()
{
Car alfaRomeo;
CallProtector callProtector;
callProtector.callProtectedMethod(&Car::updateEngine, 10);
return 0;
}
Но у меня ошибка компиляции, говорящая
no instance of function template "CallProtector::callProtectedMethod" matches the argument list
Ценю любую помощь, заранее спасибо.
2 ответа
Следующее может сработать для вас:
class CallProtector
{
public:
template<typename F, typename ...Args>
void callProtectedMethod(F&& func, Args&&... args)
{
std::lock_guard<std::mutex> guard(m_guard);
func(std::forward<Args>(args)...);
}
private:
std::mutex m_guard;
};
а затем используйте его как:
Car alfaRomeo;
CallProtector callProtector;
auto updateEngine = std::bind(&Car::updateEngine, &alfaRomeo, std::placeholders::_1);
callProtector.callProtectedMethod(updateEngine, 10);
РЕДАКТИРОВАТЬ
Или это тоже сработает:
template<typename F, typename ...Args>
void callProtectedMethod(F&& func, Args&&... args)
{
std::lock_guard<std::mutex> guard(m_guard);
std::invoke(std::forward<F>(func), std::forward<Args>(args)...);
}
а потом
callProtector.callProtectedMethod(&Car::updateEngine, alfaRomeo, 10);
Начиная с С++ 17 вы можете использовать
std::invoke
, просто перенаправив ему все аргументы:
template<typename ...Args>
void callProtectedMethod(Args&&... args)
{
std::lock_guard<std::mutex> guard(m_guard);
std::invoke(std::forward<Args>(args)...);
}
также, если вы хотите вызвать функцию-член в экземпляре автомобиля, вам нужно передать указатель на объект.