1

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

例如:我希望调用者填写列表并获取构造函数参数:

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?
4

1 回答 1

1

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

这里发生的是临时IntList从 复制构造a,并且该临时被传递给您的构造函数。a本身保持完好。

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

每当您尝试调用移动语义时,会发生什么取决于您使用的类是如何编写的。因此,没有语言保证。移动构造函数唯一需要确保的是析构函数在运行时不会搞砸。在调用移动语义后以任何方式访问对象都是错误的。

于 2013-09-07T08:59:16.530 回答