为什么将 const ref 返回值移动到另一个函数中仍然会移动构造对象?

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

在以下示例中,函数

Table::get_subtable()
返回对内部子对象 (
SubTable
) 的 const 引用。然后,该值被
std::move
d 传递到静态工厂函数
from_subtable
,该函数按值获取子表。老实说,我很惊讶这有效,甚至移动了值(检查输出)!

现场演示

#include <iostream>
#include <span>
#include <array>
#include <vector>
#include <cstdint> // click here


struct SubTable {

    SubTable() = default;

    SubTable(SubTable&& other) {
        std::cout << "Moved subtable" << std::endl; 
    }

    SubTable(const SubTable&) = default;

   static auto from_subtable(SubTable subtable) -> SubTable; 
};


auto SubTable::from_subtable(SubTable subtable) -> SubTable
{
    return subtable;
}


struct Table {
    SubTable _subtable;

    auto get_subtable() const -> const SubTable&;
};

auto Table::get_subtable() const -> const SubTable& {
    return _subtable;
}



int main()
{
    Table hello;

    auto subtable = SubTable::from_subtable(std::move(hello.get_subtable()));
}

输出:

Moved subtable

我会假设移动构造函数无法从

const&&
构造对象(我想这是我在返回值
from_subtable
之后传递给
std::move
的对象)。我的直觉是,这应该会导致编译器错误,因为我无法更改常量引用。我哪里误导了?

c++ move-semantics move-constructor
1个回答
0
投票

您误解了移动发生的位置。


auto SubTable::from_subtable(SubTable subtable) -> SubTable
{
    return subtable;
}

SubTable::from_subtable(std::move(hello.get_subtable()));

首先使用复制构造函数从

subtable
构造
const&
,然后,由于函数参数无法进行 RVO 操作,因此将
subtable
参数移动到返回槽中。

godbolt 演示显示副本

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