C++ 左值ref限定函数能否直接用于右值ref限定函数?

C++ 左值ref限定函数能否直接用于右值ref限定函数?,c++,move-semantics,C++,Move Semantics,我一直在编写以下代码来支持对右值的函数调用,而不必显式地对返回值执行std::move struct X { X& do_something() & { // some code return *this; } X&& do_something() && { // some code return std::move(*this); }}; 但这

我一直在编写以下代码来支持对右值的函数调用,而不必显式地对返回值执行
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());
    }};
这是一个有效的转换吗?为什么

另外,我也忍不住觉得在裁判资格赛中存在一些知识差距。有没有一种通用的方法(或一组规则)来判断这样的代码是否有效

这是一个有效的转换吗

对。在成员函数中,
*此
始终是左值。即使函数是右值引用限定的。这和

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
只是将左值转换为右值的命名转换。它的目的是向指定的对象发出信号,可以将其视为即将过期。由于您是在您知道这是真的(成员最初是在绑定到右值引用的对象上调用的)的上下文中执行此强制转换的,因此它不应该造成问题。

使用时,几乎是
template decltype(auto)do_something(this Self&&Self){/*some code*/return std::forward(Self);
(它也处理cv限定符,返回类型可能是对派生类的引用)。