【问题标题】:std::forward Visual Studio 13 doesn't behave like I expectstd::forward Visual Studio 13 的行为不像我预期的那样
【发布时间】:2016-11-27 09:56:28
【问题描述】:

我正在尝试学习一些基本的 C++ 11,使用 youtube 上的 Scott Meyers 讲座“An Effective C++11/14 Sampler”

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&lt;std::string&gt;(s); 的两次调用都解析为一个右值,并且发生了一个移动操作(s 被重置为 "",因为它的缓冲区被盗了)。

所以我真的不明白std::forward 有什么好处,什么时候适用。我在这里想念什么?

【问题讨论】:

  • std::string&amp;&amp; 是一个右值引用,而不是转发引用(或一段时间以来已知的“通用引用”)。

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


【解决方案1】:

在不涉及模板参数推导/引用折叠时调用 std::forward&lt;&gt; 没有意义。

转发引用(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 &&`.

【讨论】:

    【解决方案2】:

    您需要一个转发参考:

    #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

    【讨论】:

      猜你喜欢
      • 2021-12-10
      • 1970-01-01
      • 2020-03-11
      • 2016-01-28
      • 2018-12-15
      • 1970-01-01
      • 2017-04-11
      • 1970-01-01
      • 2016-12-04
      相关资源
      最近更新 更多