我有一个代码必须处理重新评估的 stl 容器。我的问题是:为什么从 rvalued-stl-container 返回元素的成员函数,例如:
vector<int>{1}.front()
返回左值而不是右值?标准指定右值对象的成员是右值。我知道我可以用 . 显式移动返回的元素std::move
。但是当返回值显然是右值时,具有左值返回类型的逻辑是什么?
如果您将这样的表达式用作某些值重载函数的参数,则会选择错误的重载并且被调用的函数将获得左值引用(很快就会变得悬空)。
出于入站右值和入站右值的精神,可能为出站右值添加outplace_front()
和outplace_back()
为更好的名称 。emplace_front()
emplace_back()
一旦编译器决定调用一个特定的成员函数(int &std::vector<int>::front()
例如),类型系统只知道int &
返回了 an,因此它必须将其视为左值,即使它的生命周期仅限于所有者临时的生命周期。
在 C++11 之前,不可能根据正在调用它的对象的值类别来重载成员函数(参见什么是“*this 的右值引用”?),仅在目的; 并且非常量临时显然不是const
,因此非const
重载必须可用。
除了您已经确定的潜在悬空左值引用之外,这在 C++03 中导致了可以使用(成员函数运算符)但不能使用(自由运算符)调用operator<<
临时的情况;C++11 用右值引用的自由运算符重载和成员函数的右值重载解决了这个问题。ostream
char
string
*this
Rvalue*this
允许三个重载front
:
T &front() & { return data_[0]; }
const T &front() const & { return data_[0]; }
T &&front() && { return std::move(data_[0]); }
右值重载的不同函数体有点笨拙。*this
这是因为 ref 限定符对成员函数体内的访问成员没有影响。