C++11 移动语义后的对象状态

C++11 移动语义后的对象状态,c++11,move-semantics,C++11,Move Semantics,我想了解移动语义和右值引用以及函数调用后的对象状态 例如:我希望调用者填充列表并进入构造函数参数: typedef std::list<int> IntList; class IntHolder { public: explicit IntHolder(IntList&& l) : m_h(l) {} private: IntList m_h; }; IntList a; a.push_back(1); IntHolder holder(a);

我想了解移动语义和右值引用以及函数调用后的对象状态

例如:我希望调用者填充列表并进入构造函数参数:

typedef std::list<int> IntList;
class IntHolder {
public:
  explicit IntHolder(IntList&& l)
    : m_h(l)
  {}
private:
  IntList m_h; 
};

IntList a;
a.push_back(1);
IntHolder holder(a);
// ... is 'a' guaranteed empty (not empty) here?
typedef std::list IntList;
类别持有人{
公众:
显式IntHolder(IntList&l)
:m_h(l)
{}
私人:
国际货币基金组织;
};
IntList a;
a、 推回(1);
国际信托持有人(a);
// ... 这里的“a”保证为空(不是空)吗?

保证a
不为空,因为它从未作为右值引用传递:它是声明的变量,不是编译器生成的临时变量,因此不能作为右值引用传递

这里发生的事情是,一个临时的
IntList
a
中构造副本,并将该临时副本传递给您的构造函数<代码>a本身保持不变

让事情变得复杂:即使是暂时的也不动!当您使用右值引用时,它会衰减为正常引用,这发生在您在初始值设定项列表中说
m_h(l)
时。否则,您将无法从构造函数中访问
l
。因此,将再次复制临时文件。您可以通过将
muh(l)
替换为
muh(std::move(l))
来强制执行移动语义


无论何时尝试调用移动语义,所发生的情况取决于所使用的类的编写方式。因此,没有语言保证。移动构造函数需要确保的唯一一件事是析构函数在运行时不会出错。调用对象上的移动语义后,以任何方式访问对象都是错误的。

a
保证不为空,因为它从未作为右值引用传递:它是声明的变量,不是编译器生成的临时变量,因此不能作为右值引用传递

这里发生的事情是,一个临时的
IntList
a
中构造副本,并将该临时副本传递给您的构造函数<代码>a本身保持不变

让事情变得复杂:即使是暂时的也不动!当您使用右值引用时,它会衰减为正常引用,这发生在您在初始值设定项列表中说
m_h(l)
时。否则,您将无法从构造函数中访问
l
。因此,将再次复制临时文件。您可以通过将
muh(l)
替换为
muh(std::move(l))
来强制执行移动语义


无论何时尝试调用移动语义,所发生的情况取决于所使用的类的编写方式。因此,没有语言保证。移动构造函数需要确保的唯一一件事是析构函数在运行时不会出错。调用对象上的移动语义后,以任何方式访问对象都是错误的。

是的,我错过了构造函数中的std::move()。在这种情况下,在构造支架后,“a”是否无效?我的误解是使用了旧的gcc版本(gcc-4.4)。在std::move-In构造函数的情况下,这个代码段被成功编译,“a”变为空(size()=0),当我尝试使用gcc 4.7时,我在将“a”作为右值传递给ctor时出现编译错误(因此我必须使用std::move来创建“holder”)。如果
a
IntHolder(a)
之后为空,这是一个编译器错误,移动语义毕竟是一个新特性。只有在使用了
IntHolder holder(std::Move(a))
时,才应该应用移动语义。是的,我错过了构造函数中的std::Move()。在这种情况下,在构造支架后,“a”是否无效?我的误解是使用了旧的gcc版本(gcc-4.4)。在std::move-In构造函数的情况下,这个代码段被成功编译,“a”变为空(size()=0),当我尝试使用gcc 4.7时,我在将“a”作为右值传递给ctor时出现编译错误(因此我必须使用std::move来创建“holder”)。如果
a
IntHolder(a)
之后为空,这是一个编译器错误,移动语义毕竟是一个新特性。仅当使用了
IntHolder(std::Move(a))
时,才应使用移动语义。