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

What is the usage of std::forward in parameter passing?

本文关键字:用法 是什么 参数传递 forward std      更新时间:2023-10-16

请参阅下面的代码段(请注意,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;  
}

如果我使用std::forward替换func(s, ':'),这没有区别,在这种情况下,foo 函数将无std::forward地进行省长转发。

C++11 中对std::forward的"省长转发"是否存在误解?

这是有区别的。在您的情况下func(s, ':')只会调用引用std::stringfunc重载。

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

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

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

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