本文介绍了rvalue refs和std :: move的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

有人可以解释为什么B不编译,但C吗?我不明白为什么std :: move是必需的,因为变量已经是一个右值引用。

Can someone explain why B doesn't compile, but C does? I don't understand why std::move is required since the variable is already an rvalue ref.

struct A {
  int x;
  A(int x=0) : x(x) {}
  A(A&& a) : x(a.x) { a.x = 0; }
};

struct B : public A {
  B() {}
  B(B&& b) : A(b) {}  // compile error with g++-4.7
};

struct C : public A {
  C() {}
  C(C&& c) : A(std::move(c)) {}  // ok, but why?
};


推荐答案

在语句中:

B(B&& b)


$ b b

参数 b 使用以下类型声明:rvalue引用 B

The parameter b is declared with the type: rvalue reference to B.

在语句中:

A(b)

表达式 b B 类型的左值。

左值表达式不能绑定到右值引用:

And lvalue expressions can not bind to rvalue references: specifically the rvalue reference in the statement:

A(A&& a)

此逻辑与语言的其他部分完全一致。考虑此功能:

This logic follows cleanly from other parts of the language. Consider this function:

void
f(B& b1, B b2, B&& b3)
{
   g(b1);
   g(b2);
   g(b3);
}

即使 f 所有声明为不同类型,表达式 b1 b2 b3 都是类型 B 的左值表达式,因此都将调用相同的函数 g 无论 g 是否重载。

Even though the parameters of f are all declared with different types, the expressions b1, b2 and b3 are all lvalue expressions of type B, and thus would all call the same function g, no matter how g is overloaded.

在C ++ 11中,变量的声明,以及使用该变量产生的表达式。和表达式从来没有引用类型。而是他们有一个值类别,正好是以下之一:lvalue,xvalue,prvalue。

In C++11 it is more important than ever to distinguish between a variable's declaration, and the expression that results from using that variable. And expressions never have reference type. Instead they have a value category of precisely one of: lvalue, xvalue, prvalue.

语句:

A(std::move(c))

是确定,因为 std :: move 返回一个右值引用。从返回右值引用的函数调用产生的表达式具有值类别:xvalue。和价值,xvalues被认为是价值。和类型 C 的右值表达式:

is ok, because std::move returns an rvalue reference. The expression resulting from a function call returning an rvalue reference has value category: xvalue. And together with prvalues, xvalues are considered rvalues. And the rvalue expression of type C:

std::move(c)

将绑定到右值引用参数: A(A&

will bind to the rvalue reference parameter in: A(A&& a).

我发现以下图表(最初由Bjarne Stroustrup发明)非常有用:

I find the following diagram (originally invented by Bjarne Stroustrup) very helpful:

       expression
          /  \
    glvalue  rvalue
     /  \    /  \
lvalue  xvalue  prvalue

这篇关于rvalue refs和std :: move的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

10-09 22:12