为什么来自 rvalued-stl-container 的元素获取者返回左值

Why element-getters from rvalued-stl-container return lvalue?

本文关键字:返回 获取 元素 rvalued-stl-container 为什么      更新时间:2023-10-16

我有一个代码必须处理重值的stl容器。我的问题是:为什么成员函数从 rvalued-stl-container 返回元素,例如:

vector<int>{1}.front()

返回左值而不是右值?标准指定右值对象的成员是右值。我知道我可以用 std::move 显式移动返回的元素。 但是,当返回值明显为右值时,使用左值返回类型的逻辑是什么?

如果您将这样的表达式用作某些价值重载函数的参数,则将选择错误的重载,并且调用的函数将获得左值引用(很快就会变得悬而未决)。

也许为出站右值添加outplace_front()outplace_back()会是更好的名称,本着emplace_front()和入站右值emplace_back()的精神。

一旦编译器决定调用一个特定的成员函数(比如int &std::vector<int>::front()),类型系统只知道返回了一个int &,所以它必须将其视为一个左值,即使它的生存期仅限于所有者的生存期。

在 C++11 之前,成员函数不可能根据调用对象的值类别进行重载(请参阅什么是"*this"的右值引用?),只能在对象的 cv 限定上;并且显然不const非常量临时,因此非const重载必须可用。

除了您确定的潜在悬而未决的左值引用外,这还导致在 C++03 中出现了临时ostream上的operator<<可以使用 char(成员函数运算符)调用但不能使用 string(自由运算符)调用的情况;C++11 通过右值引用的免费运算符重载和成员函数的右值*this重载来解决此问题。

右值*this允许front进行三次重载:

T &front() & { return data_[0]; }
const T &front() const & { return data_[0]; }
T &&front() && { return std::move(data_[0]); }

右值重载的不同函数体有点像疣;这是因为 ref-qualifier 对成员函数主体中的 *this 访问成员没有影响。