我正在阅读Stroustrup的一本教科书,以了解rvalue的概念并移动构造函数:
第一个近似值是您无法分配的值 ,例如函数调用返回的整数和右值 reference是对其他人无法分配的内容的引用。 Vectors的operator +()中的res局部变量就是一个例子。
上面引用的代码在下面列出。
问题:局部变量res
可以合法出现在分配的左侧,例如在res=nullptr
中。为什么将其视为右值?
Vector operator+(const Vector& a, const Vector& b) {
if (a.size()!=b.size()) throw Vector_size_mismatch{};
Vector res(a.size());
for (int i=0; i!=a.size(); ++i) res[i]=a[i]+b[i];
return res;
}
答案 0 :(得分:2)
否,局部变量不是右值。在您的示例中,右值是临时对象,该临时对象是函数返回的res副本(尽管可以省略对复制构造函数或move构造函数的调用)。
res
本身是函数中的左值。
答案 1 :(得分:1)
Vectors的operator +()中的res局部变量是一个示例。
这是错误的。 res
是左值的主要示例。我有点担心你的教科书。我们没有太多背景信息,因此这可能只是拼写错误或措辞误导的一个例子。但是,如果这是一个真正的错误,则表明作者严重缺乏对该语言基础知识的了解。
通常的经验法则是:“如果它具有名称,则不能为右值。即使它起初看上去有些混乱,它也能很好地工作。例如:
// A temporary has no name.
// Therefore: Can call foo() with it.
foo(Object());
void foo(Object&& o)
{
// o has a name. Therefore: not an rvalue.
// Therefore: Must move.
bar(std::move(o));
}
void bar(Object&& o)
{
// ...
}
该规则在您的代码段中也同样适用:
.size()
返回值:无名称-> rvalue a
,b
,res
,i
的名称->不是右值i!=a.size()
布尔值:无名称-> rvalue a[i]+b[i]
临时符号:无名称-> rvalue 只有函数的返回值比较棘手,因为返回值优化(RVO)在这里起作用。经验法则是:“如果您返回本地变量,通常不需要std :: move()它。”