相关疑难解决方法(0)

什么是右值,左值,x值,glvalues和prvalues?

在C++ 03中,表达式是rvaluelvalue.

在C++ 11中,表达式可以是:

  1. 右值
  2. 左值
  3. x值
  4. glvalue
  5. prvalue

两类已成为五大类.

  • 这些新的表达类别是什么?
  • 这些新类别如何与现有的左值和左值类别相关联?
  • C++ 0x中的右值和左值类别是否与它们在C++ 03中的相同?
  • 为什么需要这些新类别?是WG21神只是想迷惑我们凡人?

c++ expression c++-faq c++11

1291
推荐指数
13
解决办法
17万
查看次数

为什么我需要在move-constructor的初始化列表中使用std :: move?

假设我有一个(普通的)类,它是可移动构造和可移动分配但不可复制构造或可复制分配:

class movable
{
  public:
    explicit movable(int) {}
    movable(movable&&) {}
    movable& operator=(movable&&) { return *this; }
    movable(const movable&) = delete;
    movable& operator=(const movable&) = delete;
};
Run Code Online (Sandbox Code Playgroud)

这很好用:

movable m1(movable(17));
Run Code Online (Sandbox Code Playgroud)

当然,这不起作用,因为m1它不是右值:

movable m2(m1);
Run Code Online (Sandbox Code Playgroud)

但是,我可以包m1std::move,它投射到一个右值引用,以使其工作:

movable m2(std::move(m1));
Run Code Online (Sandbox Code Playgroud)

到现在为止还挺好.现在,假设我有一个(同样微不足道的)容器类,它包含一个值:

template <typename T>
class container
{
  public:
    explicit container(T&& value) : value_(value) {}
  private:
    T value_;
};
Run Code Online (Sandbox Code Playgroud)

但是,这不起作用:

container<movable> c(movable(17));
Run Code Online (Sandbox Code Playgroud)

编译器(我试过clang 4.0和g ++ 4.7.2)抱怨我正在尝试movablecontainer初始化列表中使用已删除的复制构造函数.同样,包裹valuestd::move使得它的工作:

    explicit container(T&& value) : value_(std::move(value)) {} …
Run Code Online (Sandbox Code Playgroud)

c++ rvalue-reference move-constructor move-semantics c++11

14
推荐指数
2
解决办法
2600
查看次数

右值到左值的转换和“named-refs-are-lvalues”规则

有很多与右值相关的问题,但我没有找到这些确切问题的答案。

我无法完全理解“命名引用是左值引用”的经验法则。

这看起来真的很奇怪——我们将引用声明为右值,但由于我们必须以某种方式使用这个引用(否则,有什么意义?),我们命名它,因为它被命名为它毕竟是一个左值!

考虑这段代码:

int&& foo(int&& arg)
{
    arg = 10;
    return arg; // ERROR, `arg` is an lvalue since it's named!
}
foo(1);
Run Code Online (Sandbox Code Playgroud)

问题是:

  1. arg 到底什么时候变成左值?
  2. 如果函数为 void 并且 b) 和 c) 行不存在,则 arg 的类型是什么?
  3. 很多文章(仅引用第一个找到的结果)说可能存在隐式左值到右值的转换,但相反的方向是不可能的 - 为什么?此示例显示-s 从toarg转换,然后尝试隐式转换为which 导致编译错误 - 只是相反的行为!这就是为什么我们需要它基本上是一个显式的 static_cast 到右值类型。int&&int&int&int&&std::move

c++ rvalue-reference c++11

2
推荐指数
1
解决办法
727
查看次数