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

标签 c++ move-semantics

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

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

此外,我不禁觉得在引用限定符方面存在一些知识差距。是否有一种通用方法(或一组规则)来确定这样的代码是否有效?

最佳答案

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也没有问题。第一个重载只能返回左值引用,因为据它所知,它是在左值上调用的。同时,第二个重载有额外的信息,它知道它最初是在右值上调用的。因此,它会根据附加信息进行额外的转换。

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

关于c++ - 左值引用限定函数可以直接在右值引用限定函数中使用吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62017581/

相关文章:

c++ - 为什么 std::set::erase 与 std::set::insert 不一致?

c++ - vector 增长时如何强制执行 move 语义?

c++ - move 自定义容器的构造函数?

c++ - 将 std::vector<T> move 到 T*

c++ - "xvalue has identity"是什么意思?

c++ - C/C++ 命令行程序的回归测试

c++ - 将 GL_UNSIGNED_BYTE 上传到 GL_FLOAT 纹理

c++ - 自动使用派生类

c++ - 如何转发元组的值? std::get(move(tuple))vs.forward(std::get(tuple))

c++ - 在 QT 对象类中声明一个 PCL 点云