首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >std::move和std::forward之间的混淆

std::move和std::forward之间的混淆
EN

Stack Overflow用户
提问于 2018-02-19 11:57:26
回答 1查看 245关注 0票数 0

因此,为了理解我的理解,我只是在编写一个std::forward的示例和人为的示例,但是它并没有像我所期望的那样工作。在下面的程序中

代码语言:javascript
复制
#include <string>
#include <iostream>

struct A
{
    A(const std::string& m) : m_(m) {};
    std::string m_;
};

template<typename T>
void funcB(T&& obj)  // universal reference
{
    std::string local = std::move(obj.m_);   // using std::move on universal reference. Bad.
    std::cout << "funcB : " << local << '\n';
}

template<typename T>
void funcC(T&& obj)  // universal reference
{
    std::string local = std::forward<std::string>(obj.m_);   // using std::move on universal reference
    std::cout << "funcC : " << local << '\n';
}

template<typename T>
void funcD(T&& obj)  // universal reference
{
    T local = std::forward<T>(obj);   // using std::move on universal reference
    std::cout << "funcD : " << local.m_ << '\n';
}

int main()
{
    A obj("firstString");

   //funcA(obj);  // We get compiler error. Rvalue reference cannot be bound to Lvalue
    funcB(obj);  
    std::cout << "Main : " <<  obj.m_ << '\n';

    A obj2("secondString");
    funcC(obj2);
    std::cout << "Main : " << obj2.m_ << '\n';

    A obj3("thirdString");
    funcD(obj3);
    std::cout << "Main : " << obj3.m_ << '\n';
}

在输出中

代码语言:javascript
复制
funcB : firstString
Main : 
funcC : secondString
Main : 
funcD : thirdString
Main : thirdString

funcC中,即使我使用了通用引用,并且在这里它被绑定到Lvalue,当我执行std::forward<std::string>时,字符串也会被移动。因此,在最后一行中,在"Main:“之后没有输出。尽管obj被绑定到Lvalue,但有人能不能了解字符串是如何移动的呢?

在重读了一本书之后,才意识到了这个问题的答案。

在funcC中,std::forward<std::string>(obj.m_)等同于移动字符串。但是在funcD中,std::forward被实例化为std::forward<struct A&>(obj),这是复制的。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2018-02-19 12:05:37

在这两种情况下,您都要使用一个rvalue引用作为参数来构造一个字符串std::string local。因此,local是通过该引用从引用的原始对象移动到的。

这与std::forwardstd::move没有多大关系;而且,您没有初始化一个引用(在Meyers的文本中,“绑定对lvalue的引用”;引用将出现在LHS上)--您只是从另一个对象构造一个对象。

然而,如果不编写std::forwardstd::move,您将最终复制这些函数参数,因为rvalue引用将被删除在local声明的初始化部分。

因此,在这种情况下,std::forwardstd::move具有相同的效果。然而,它们不是一回事,一般不应被视为可互换的。有关更多信息,请阅读以下内容:

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/48865711

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档