1

请参阅下面的代码段(注意 s 是一个带有 char 而不是字符串的数组):

#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, ':')using std::forward,则没有区别,std::forward在这种情况下, foo 函数将执行完美转发。

std::forward在 C++11 中是否存在对“完美转发”的误解?

4

2 回答 2

5

它有所作为。在您的情况下func(s, ':'),只会调用func引用 a的重载std::string

std::forward问题是命名变量和参数本身就是左值,这也是最初存在的原因。

在您的示例中,foo即使您不使用std::forward. 这只是因为您实际上foo使用一个char[]参数调用,该参数用于隐式构造一个临时的std::string.

于 2014-01-19T17:32:36.267 回答
1

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

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

于 2014-01-19T17:35:07.010 回答