Is this a perfect forwarding function? Or does the creation of a temporary T make it non-perfect? T is a trivial class.
template<class T, typename... Args>
void foo(Args&&... args)
{
bar(T{std::forward<Args>(args)...});
}
If it is a perfect forwarding function I expect it to incur no overhead, but creating a T must incur overhead unless a suitable optimisation is available to the compiler.
Perfect forwarding doesn't mean no overhead, and in current C++, perfect forwarding always has the potential to create undesired temporary objects. For example:
In the call
foo(getC()), guaranteed copy elision occurs, and the return statement ingetCconstructs theCobject directly into the parametercoffoo, with no copies or moves taking place. In the callbar(getC()), which uses perfect forwarding, the prvaluegetC()is materialized first in order to be bound to the reference parameter ofbar, and then the move constructor ofCis called in order to initializecfromstd::forward<Arg>(arg).You might say that perfect forwarding isn't perfect.
Anyway, what "perfect forwarding" means, then, is that lvalues are forwarded as lvalues of the same type, and rvalues are forwarded as rvalues of the same type. In your original example, lvalues passed to
fooare forwarded as lvalues of the same type to the constructor ofT, and rvalues passed tofooare forwarded as rvalues of the same type to the constructor ofT. So yes, you have perfect forwarding here.