左值引用限定函数可以直接在右值引用限定函数中使用吗?

Can a lvalue-ref-qualified function be used directly in a rvalue-ref-qualified function?

我一直在编写以下代码来支持对右值的函数调用,而无需在 return 值上显式 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());
    }};

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

此外,我不禁觉得在 w.r.t ref-qualifiers 方面存在一些知识差距。是否有通用的方法(或一组规则)来确定这样的代码是否有效?

Is this a valid transformation?

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

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

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

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

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

std::move 只是将左值转换为右值的命名转换。它的目的是向指定的对象发出信号,就好像它即将过期一样。由于您是在您知道这是真的上下文中执行此转换(该成员最初是在绑定到右值引用的对象上调用的),所以它应该不会造成问题。