I was asking earlier about the difference between
template<typename... Args> void f(Args... args){ call(args...); }
andtemplate<typename... Args> void f(Args&&... args){ call(std::forward<Args>(args)...); }
For which I got a good response and a link to an article that sort of made sense. Upshot was that the second version was to be preferred.So I went to update some of my library. First of all, I had a perfect forwarding constructor to a class which I changed and this works fine:
template<typename T> class BlendValue
{
public:
template<typename... Args> BlendValue(Args&&... args) : v(std::forward<Args>(args)...), o(v) { }
};
However, I also have a signals/slots implementation which tries to use perfect forwarding for the call of the signal. My previous version looked like this:template<typename... Args> void Signal<Args...>::operator()(Args... args)
{
//snip
for(auto &n: v) n->call(args...); // call back the slots
//snip
}
When I changed this to:template<typename... Args> void Signal<Args...>::operator()(Args&&... args)
{
//snip
for(auto &n: v) n->call(std::forward<Args>(args)...); // call back the slots
//snip
}
elsewhere in the library, where I declare a signal simply as:Signal<bool> activated;
void ApplicationEvents::onActivated(bool state)
{
activated(state);
}
The compiler (GCC) is throwing an error:cannot bind 'bool' lvalue to 'bool&&'
Now, when I use my original code, without the && and the std::forward<>, everything works. I've tested and I can create signals and trigger them with value types, reference types, even const reference types that can be given temporaries as the call parameter. So the original version works and does everything I want.But it is all contrary to the expert advice I am being given, so I wondered if anyone could shed any light on the compiler error I am getting and explain what is happening here?
Thanks in advance.