C++ std::forward在参数传递中的用途是什么?
请参阅下面的代码(注意,s是一个带有char而不是string的数组):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[]
#包括
#包括
#包括
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;
}