我正在做一些实验,试图了解转发的工作原理,但我遇到了我不明白的情况。
当我用 clang 3.8 -O3 编译时
class Foo {
Foo(const std::string& s) : str(s) {}
std::string str;
};
和
class Foo {
Foo(std::string&& s) : str(std::forward<std::string&>(s)) {}
std::string str;
};
在第一种情况下使用 Foo foo("this is a test")
构造 Foo 几乎快 2 倍。
为什么?
最佳答案
您需要使用 std::forward
进行完美转发仅在处理 forwarding references 时.转发引用仅存在于模板推导的上下文中。
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));
}
我会这样写你的代码:
class Foo {
template<typename T>
Foo(T&& s)
: str(std::forward<decltype(s)>(s)) {}
std::string str;
};
关于C++ 右值引用转发性能,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34560175/