参数传递中std :: forward的用法是什么?

时间:2014-01-19 17:25:05

标签: c++ c++11 forward perfect-forwarding

请参阅下面的代码段(注意s是带char而不是string的数组):

#include <string>
#include <iostream>
#include <utility>

void func(std::string & s, char a) {
  std::cout << "here1" << std::endl;
  // ...
}

void func(std::string && s, char a) {
  std::cout << "here2" << std::endl;
  // ...
}

template <class T>
void foo(T && s) {
  std::cout << "foo2" << std::endl;
  func(s, ':');
  //func(std::forward<T>(s), ':');
}

int main(int agrc, char *argv[])
{
  //std::string s("a:b:c:d");
  char s[8] = "abcdefg";
  foo(std::move(s));
  std::string s2("abcd")
  foo(s2);
  return 0;  
}

如果我使用func(s, ':')替换std::forward,则没有区别,在这种情况下,foo函数将执行完美转发而不使用std::forward

在C ++ 11中,对std::forward的'完美转发'是否有误解?

2 个答案:

答案 0 :(得分:5)

它有所不同。在您的情况下,func(s, ':')只会调用引用func的{​​{1}}重载。

问题在于命名变量和参数本身就是左值,这也是std::string首先存在的原因。

在您的示例中,即使您不使用std::forward,也会为第一次调用foo选择正确的重载。这只是因为您实际上使用std::forward参数调用foo,该参数用于隐式构造char[]的临时值。

答案 1 :(得分:1)

让我们考虑第一个案例foo(std::move(s))。在foo内,s将绑定到右值。但由于它有一个名称(s),它不再是右值。因此,当您将s传递给func时,就像将左值传递给它一样 - 它会触发here1版本。但是,如果您通过s传递std::forward,它将再次成为右值。

在第二种情况下,当输入foo时,s是左值引用,因此无论是直接传递还是通过std::forward传递它都不会改变任何内容。您需要使用std::move再次从s中获取rvalue。