可以将带左值引用的函数直接用于带右值引用的函数?

问题描述 投票:2回答:1

我一直在编写以下代码来支持对rvalue的函数调用,而不必在返回值上显式地std::move

struct X {
    X& do_something() & {
        // some code

        return *this;
    }

    X&& do_something() && {
        // some code

        return std::move(*this);
    }};

但是这导致必须在函数内部重复代码。最好,我会做类似的事情

struct X {
    X& do_something() & {
        // some code

        return *this;
    }

    X&& do_something() && {
        return std::move(do_something());
    }};

这是有效的转换吗?为什么或为什么不呢?

[此外,我不禁感到引用裁判限定词存在一些知识鸿沟。是否有一种通用的方法(或一组规则)来确定类似这样的代码是否有效?

c++ move-semantics
1个回答
3
投票

这是有效的转换吗?

是。在成员函数*this中始终是一个左值。即使该函数是右值引用限定的。与

相同
void foo(bar& b) { /* do things */ }

void foo(bar&& b) {
  // b is an lvalue inside the function
  foo(b); // calls the first overload
}

因此,您可以使用左值ref限定函数来共享实现。

并且在结果上使用std::move也没有问题。第一个重载只能返回一个左值引用,因为据它所知,它是在一个左值上调用的。同时,第二个重载具有额外的信息,它知道它最初是在右值上调用的。因此,它会根据其他信息进行额外的转换。

std::move只是将左值转换为右值的命名转换。其目的是发信号通知指定的对象可以被视为即将过期。由于您是在知道其为真的上下文中进行此转换的(该成员最初是在绑定到右值引用的对象上调用的),因此它不会造成问题。

© www.soinside.com 2019 - 2024. All rights reserved.