c ++ rvalue引用转发性能

时间:2016-01-01 21:20:23

标签: c++ c++11

我正在做一些实验,试图了解转发是如何工作的,并且我遇到了我不理解的情况。

当我用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倍。

为什么?

2 个答案:

答案 0 :(得分:7)

只有在处理forwarding references时才需要使用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));
}

我会写这样的代码:

class Foo {
  template<typename T> 
  Foo(T&& s) 
      : str(std::forward<decltype(s)>(s)) {}

  std::string str;
};

答案 1 :(得分:2)

我认为这应该是一个移动构造函数,因此应该使用std::move

class Foo {
  Foo(std::string&& s) : str(std::move(s)) {}

  std::string str;
};

std::forward只对斯科特迈尔斯所称的&#34;通用引用&#34;,这是rvalue引用的一个子集才有意义 - 维托里奥在他的回答中谈到了这一点。