I am doing some experiments to try to understand how forwarding works and I get to situation where I do not understand.
When I compile with clang 3.8 -O3
class Foo {
Foo(const std::string& s) : str(s) {}
std::string str;
};
and
class Foo {
Foo(std::string&& s) : str(std::forward<std::string&>(s)) {}
std::string str;
};
Constructing Foo with Foo foo("this is a test") in the first case is almost 2 times faster.
Why?
You need to perfect-forward using std::forward only when dealing with forwarding references. Forwarding references only exist in the context of template deduction.
void f(std::string&& x): x is a regular rvalue-reference, because no template type deduction is taking place.
template<typename T> void f(T&& x): x is a forwarding reference, because of T template deduction.
Generally, you don't want to use std::forward unless you're dealing with forwarding references.
When calling std::forward, you have to pass the exact type of the forwarded value. This can be done as such: std::forward<decltype(x)>(x).
Or as such, when you have a name for the deduced type:
template<typename T>
void f(T&& x)
{
something(std::forward<T>(x));
}
I would write your code like this:
class Foo {
template<typename T>
Foo(T&& s)
: str(std::forward<decltype(s)>(s)) {}
std::string str;
};
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With