C++ 中的局部变量是右值吗?
Are local variables rvalues in C++?
我正在阅读 Stroustrup 的教科书以了解右值和移动构造函数的概念:
an rvalue is – to a first approximation – a value that you can’t assign
to, such as an integer returned by a function call, and an rvalue
reference is a reference to something that nobody else can assign to.
The res local variable in operator+() for Vectors is an example.
上面引用的代码如下所列。
问题:局部变量 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;
}
不,局部变量不是右值。在您的示例中,右值是函数返回的临时对象,它是 res 的副本(尽管可以省略复制构造函数或移动构造函数的调用)。
res
本身是函数内的左值。
The res local variable in operator+() for Vectors is an example.
这是错误的。 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()
return 值:无名称 -> 右值
a
、b
、res
、i
有名称 -> 不是右值
i!=a.size()
布尔值:无名称 -> 右值
-
a[i]+b[i]
临时:无名称 -> 右值
只有函数的 return 值比较棘手,因为 return 值优化 (RVO) 在这里发挥作用。这里的经验法则是:“如果你 return 一个局部变量,通常不需要 std::move() 它。”
我正在阅读 Stroustrup 的教科书以了解右值和移动构造函数的概念:
an rvalue is – to a first approximation – a value that you can’t assign to, such as an integer returned by a function call, and an rvalue reference is a reference to something that nobody else can assign to. The res local variable in operator+() for Vectors is an example.
上面引用的代码如下所列。
问题:局部变量 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;
}
不,局部变量不是右值。在您的示例中,右值是函数返回的临时对象,它是 res 的副本(尽管可以省略复制构造函数或移动构造函数的调用)。
res
本身是函数内的左值。
The res local variable in operator+() for Vectors is an example.
这是错误的。 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()
return 值:无名称 -> 右值 a
、b
、res
、i
有名称 -> 不是右值i!=a.size()
布尔值:无名称 -> 右值-
a[i]+b[i]
临时:无名称 -> 右值
只有函数的 return 值比较棘手,因为 return 值优化 (RVO) 在这里发挥作用。这里的经验法则是:“如果你 return 一个局部变量,通常不需要 std::move() 它。”