【问题标题】:Is the r-value parameter really an l-value parameter inside the function scope?右值参数真的是函数范围内的左值参数吗?
【发布时间】:2020-05-13 08:14:54
【问题描述】:

我在实现list 类的代码中发现了以下sn-p

    void push_front( const T & x ) { insert( begin( ), x ); }

    void push_front( T && x ) { insert( begin( ), std::move( x ) );}

现在我知道,如果我有一个函数将参数作为r-value,那么该参数将是函数范围内的l-value(不是吗?)。

所以我可以用

替换之前的sn-p
void push_front( const T & x ) { insert( begin( ), x ); }

void push_front( T && x ) { push_front( x );}

第一个问题:我说的对吗?

第二个:考虑到第一个sn-p中的r-value参数是第二个函数中的l-value参数,将std::move( x )xl-value转换为r-value和函数push_front() 调用r-value 版本的函数insert() 还是什么?

编辑::

insert() 就是这样实现的

    iterator insert( iterator itr, const T & x )
    {
        Node *p = itr.current;
        theSize++;
        return { p->prev = p->prev->next = new Node{ x, p->prev, p } };
    }


    iterator insert( iterator itr, T && x )
    {
        Node *p = itr.current;
        theSize++;
        return { p->prev = p->prev->next = new Node{ std::move( x ), p->prev, p } };
    }

Node的定义

struct Node
    {
        private:
        T data;
        Node *prev;
        Node *next;

        Node( const T & d = T{ }, Node * p = nullptr,
        Node * n = nullptr )//It's possible because of const
        :data{ d }, prev{ p }, next{ n } { }

        Node( T && d, Node * p = nullptr, Node * n = nullptr )
        : data{ std::move( d ) }, prev{ p }, next{ n } { }
    };

【问题讨论】:

  • 您建议的替换将复制参数,而不是像第一个示例那样移动它。你做出改变是否正确取决于这是否是你想要的行为......
  • 几乎所有你想知道的都可以在这里找到:stackoverflow.com/questions/3106110/what-is-move-semantics
  • @M.M 我的意思是如果std::move(x) 将x 转换为rvalue,那么将调用push_front(T&& ) 而不是push_front(const T& )
  • @MM 如果我只有两个版本的push_front()(即)push_front(T&& )push_front(const T& ),因此我的对象不会被复制,我的替换会更好,不是吗?
  • @anonymous 您的替换将复制对象而不是移动它。代码push_front( std::move(x) ) 移动对象而push_front(x) 不移动

标签: c++ move-semantics lis


【解决方案1】:

我有一个函数将参数作为右值,该参数将是函数范围内的左值

是的。一般来说,所有的右值引用变量都是左值,函数参数与否。

所以我可以将之前的 sn-p 替换为 ...

是的,但是push_front(T &&x) 将复制x 而不是移动它。

std::move( x )将x从左值转换为右值,函数push_front()调用右值版本的函数insert()

是的。

【讨论】:

  • 第二个答案你不是说要复制而不是移动吗?
  • 如果我只有两个版本的 push_front()(即)push_front(T&& )push_front(const T& ),那么我的对象不会被复制,我的替换会更好,不是吗?
  • 一般来说,所有的右值引用都是左值,函数参数与否。这是错误的。对返回右值引用的函数的调用不是左值。
  • @anonymous push_front(const T& ) 复制对象。由于您的push_front(T&& ) 使用push_front(const T& ),它也会复制。
  • @anonymous 是的,这是你的副本::data{ d }
猜你喜欢
  • 2013-07-12
  • 1970-01-01
  • 1970-01-01
  • 2014-08-09
  • 2018-12-18
  • 1970-01-01
  • 1970-01-01
  • 2020-05-25
  • 1970-01-01
相关资源
最近更新 更多