C++ std::forward在参数传递中的用途是什么?

C++ std::forward在参数传递中的用途是什么?,c++,c++11,forward,perfect-forwarding,C++,C++11,Forward,Perfect Forwarding,请参阅下面的代码(注意,s是一个带有char而不是string的数组): #包括 #包括 #包括 void func(std::string&s,char a){ std::cout这会有所不同。在您的情况下,func(s,,:')将只调用引用std::string的func重载 问题是命名变量和参数本身就是左值,这也是为什么std::forward首先存在的原因 在您的示例中,它的外观是为第一次调用foo选择了正确的重载,即使您没有使用std::forward。这只是因为您实际使用char[]

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

#包括
#包括
#包括
void func(std::string&s,char a){

std::cout这会有所不同。在您的情况下,
func(s,,:')
将只调用引用
std::string
func
重载

问题是命名变量和参数本身就是左值,这也是为什么
std::forward
首先存在的原因


在您的示例中,它的外观是为第一次调用
foo
选择了正确的重载,即使您没有使用
std::forward
。这只是因为您实际使用
char[]调用
foo
参数,该参数用于隐式构造std::string的临时变量,它会起作用。在您的情况下,
func,,:'
将只调用引用
std::string
func
重载

问题是命名变量和参数本身就是左值,这也是为什么
std::forward
首先存在的原因


在您的示例中,它的外观是为第一次调用
foo
选择了正确的重载,即使您没有使用
std::forward
。这只是因为您实际使用
char[]调用
foo
< /代码>参数,用于隐式构造一个临时的<代码> STD::String

让我们考虑第一种情况<代码> FoO(STD::Stand(s))。在<代码> Foo中,<代码> s>代码>将绑定到rVal.但是因为它有一个名称(<代码> s < /代码>)它不再是右值。因此,当您将

s
传递到
func
时,它将像传递左值一样-它将触发
此处1
版本。但如果您将
s
通过
std::forward
传递,它将再次成为右值


<第二种情况>代码> S/<代码>在输入FoO时是LValk引用,所以无论您直接通过还是通过<代码> STD::向前/<代码>,都不会改变任何东西。您需要使用<代码> STD::移动< /代码>再次从 S/<代码>中获得rValuy。

让我们考虑第一种情况<代码> FoO(STD::移动(s))

。在
foo
的内部,
s
将绑定到右值。但由于它有一个名称(
s
)它不再是右值。因此,当您将
s
传递到
func
时,它将像传递左值一样-它将触发
此处1
版本。但如果您将
s
通过
std::forward
传递,它将再次成为右值


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

注意,在将
s
从..移动到
后,您不应该使用它>std::forward
我得到
here2
然后
here1
,正如预期的那样。@chris我不同意。对象的状态将是未定义的,但仍然有效(尤其是
运算符=
)@pmr,这一点不错,但比以后发生不好的事情更安全。您的更新正在调用
foo(char*&&&&&&
func>(std::string&
由于
std::string
的隐式构造函数。请注意,在将
s
从..移动后,您不应该使用它,并且使用
std::forward
我得到
here2
然后
here1
,正如预期的那样。@chris我不同意。对象的状态将是未定义的,但仍然有效(特别是
operator=
)@pmr,这一点不错,但比以后发生的不好的事情更安全。您的更新正在调用
foo(char*&&)
func(std::string&&)
由于@xunzhang的隐式构造函数
std::string
,您的示例不好。因为在第一种情况下
foo
使用数组类型并在调用站点构造临时数组。这就是为什么您认为选择了正确的重载。我修复了您的示例:@xunzhang您的示例不好。因为在第一种情况下
fooe> 使用数组类型并在调用站点构造临时。这就是为什么您认为选择了正确的重载。我修复了您的示例:
#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;  
}