我正在尝试学习一些基本的C ++ 11,在youtube上使用Scott Meyers讲座"一个有效的C ++ 11/14采样器"
https://www.youtube.com/watch?v=BezbcQIuCsY
使用他的std::forward
示例代码(讲座中的第19分钟),我编写了以下代码来理解std::forward
#include "stdafx.h"
#include <string>
#include <utility>
class A
{
public:
void Foo(std::string&& s)
{
std::string s2 = std::forward<std::string>(s);
}
};
int _tmain(int argc, _TCHAR* argv[])
{
A a;
std::string s3 = "Hello World";
a.Foo(s3);
a.Foo("Hello World");
return 0;
}
令人惊讶的是它没有编译,a.Foo(s3)
无法从左值隐式地转换为右值。所以我将a.Foo(s3);
更改为a.Foo(std::move(s3));
现在它已编译。
然而,在对Foo std::forward<std::string>(s);
的两次调用都解析为rvalue并且发生了Move操作时(s被重置为""
,因为它的缓冲区被盗了)。
所以我真的不明白什么是好std::forward
以及何时适用。我在这里错过了什么?
答案 0 :(得分:2)
当没有涉及模板参数扣除/参考折叠时调用std::forward<>
没有意义。
转发参考(Scott Meyers曾经称之为“通用参考”)的意思是,取决于您所接收的价值类别,您也可以转发该价值类别。
但是在这里,你不会对价值类别的含义感到困惑,它是静态的。
这是一个具有模板参数推导的上下文:
template<typename T>
void f(T&& t) // T is to be deduced, && might be collapsed
{
g(std::forward<T>(t)); // will keep the category value
}
f(std::string{"hey"}); // T inferred std::string&&, so the parameter type is `std::string&& &&`, which is collapsed to `std::string &&`.
答案 1 :(得分:0)
您需要转发参考:
#include <string>
#include <utility>
class A
{
public:
template <typename String>
void Foo(String&& s)
{
std::string s2 = std::forward<String>(s);
}
};
int main()
{
A a;
std::string s3 = "Hello World";
a.Foo(s3);
a.Foo("Hello World");
return 0;
}