我正在做一些实验,试图了解转发是如何工作的,并且我遇到了我不理解的情况.
当我用clang 3.8 -O3编译时
class Foo {
Foo(const std::string& s) : str(s) {}
std::string str;
};
Run Code Online (Sandbox Code Playgroud)
和
class Foo {
Foo(std::string&& s) : str(std::forward<std::string&>(s)) {}
std::string str;
};
Run Code Online (Sandbox Code Playgroud)
Foo foo("this is a test")在第一种情况下构造Foo 几乎快2倍.
为什么?
std::forward只有在处理转发引用时才需要完美转发.转发引用仅存在于模板推导的上下文中.
void f(std::string&& x):x是一个常规的右值引用,因为没有发生模板类型推导.
template<typename T> void f(T&& x):x是一个转发引用,因为T模板扣除.
通常,std::forward除非您正在处理转发引用,否则您不想使用.
调用时std::forward,您必须传递转发值的确切类型.这可以这样做:std::forward<decltype(x)>(x).
或者,当您有推导类型的名称时:
template<typename T>
void f(T&& x)
{
something(std::forward<T>(x));
}
Run Code Online (Sandbox Code Playgroud)
我会写这样的代码:
class Foo {
template<typename T>
Foo(T&& s)
: str(std::forward<decltype(s)>(s)) {}
std::string str;
};
Run Code Online (Sandbox Code Playgroud)