std :: forward Visual Studio 13的行为并不像我期望的那样

时间:2016-07-23 17:03:31

标签: c++ c++11 visual-c++ visual-studio-2013

我正在尝试学习一些基本的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以及何时适用。我在这里错过了什么?

2 个答案:

答案 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;
}

live example