我想了解移动语义和右值引用以及函数调用后的对象状态。
例如:我希望调用者填充列表并获取构造函数参数:
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?
答案 0 :(得分:1)
a
保证不为空,因为它从未作为右值引用传递:它是声明的变量,而不是编译器生成的临时变量,因此不能作为右值引用传递。
这里发生的事情是,临时IntList
从a
获取副本构造,并将临时传递给您的构造函数。 a
本身保持不变。
让事情变得非常复杂:即使是暂时的也不会被移动!当您使用右值引用时,它会衰减为正常引用,当您在初始化列表中说m_h(l)
时会发生这种情况。如果不是这样,您将无法从构造函数中访问l
。所以,临时是第二次复制。您可以将m_h(l)
替换为m_h(std::move(l))
来强制执行移动语义。
每当您尝试调用移动语义时,会发生什么取决于您正在使用的类的编写方式。因此,没有语言保证。移动构造函数唯一需要确保的是析构函数在运行时不会搞砸。在对象上调用移动语义后,以任何方式访问对象只是一个错误。