在以下示例中,函数
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
的对象)。我的直觉是,这应该会导致编译器错误,因为我无法更改常量引用。我哪里误导了?
您误解了移动发生的位置。
auto SubTable::from_subtable(SubTable subtable) -> SubTable
{
return subtable;
}
SubTable::from_subtable(std::move(hello.get_subtable()));
首先使用复制构造函数从
subtable
构造const&
,然后,由于函数参数无法进行 RVO 操作,因此将 subtable
参数移动到返回槽中。