The problem is that you're explicitly specifying the template parameter as an int
. As Nawaz mentioned, Args&&...
gets expanded into int&&
and you can't bind an lvalue to an rvalue reference.
The reason perfect forwarding works is that when you call a function (for example) without specifying the template arguments, they get deduced to either &
or &&
and then the references collapse (read about reference collapsing if you don't know what that is). You do explicitly specify it though, so you inhibit reference collapsing and screw it all up.
One thing you could do is give the operator()
it's own list of template arguments:
template<typename... Args2>
void operator ()(Args2&&... args) const;
...
template< typename... Args >
template< typename... Args2 >
void Signal< Args... >::operator ()(Args2&&... args) const
{
for (const Delegate& delegate : _delegates)
delegate(std::forward< Args2 >(args)...);
}
This way you can let reference collapsing take care of it for you.