Вы можете подумать, что ваш operator()
использует идеальную пересылку, но это не так. Аргумент шаблона Args...
полностью разрешается к тому времени, когда рассматривается метод operator()
, поэтому он просто принимает все аргументы как обычные ссылки RValue.
Из-за этого переопределение должно делать то же самое :
class MyClassWithListener : public WithListeners<int>::Listener{
public:
virtual void operator()(int&& value) override {
//my handling code
}
};
Вы бы лучше обслужили просто go с прямыми аргументами в этом случае:
template <typename... Args>
class WithListeners {
public:
class Listener {
public:
virtual void operator()(Args... args) = 0;
};
void callListeners(Args... args) const {
for (auto l : listeners) {
if (l) (*l)(std::move(args)...);
}
}
};
Поскольку вы все еще можете полностью определить аргументы слушателя:
class MyClassWithListener : public WithListeners<const int&>::Listener{
public:
virtual void operator()(const int& value) override {
//my handling code
}
};