`[](std::list<int>& list){return std::move(list)}(list)` 是否保证将 `list` 留空?

Is `[](std::list<int>& list){return std::move(list)}(list)` guaranteed to leave `list` empty?

更具体地说:

struct A{
    std::list<int> list;
    std::list<int> foo(){
        return std::move(list);
    }
}

A a;
// insert some elements into a.list
a.foo(); // is this guaranteed to clear a.list?

上面最后一行是否保证 a.list 为空?

没有。从大多数标准库 类 中移出,将它们留在 "valid but unspecified state" [1] 中。这意味着您必须明确清除 a.list 以确保它在移动后为空。

[1] 此规则有例外情况:最值得注意的是,std::unique_ptr 必须在移动后为空。

Is the last line above guaranteed to leave a.list empty?

没有。标准如下:

[lib.types.movedfrom]

Objects of types defined in the C++ standard library may be moved from ([class.copy.ctor]). Move operations may be explicitly specified or implicitly generated. Unless otherwise specified, such moved-from objects shall be placed in a valid but unspecified state.

这是有效但未指定状态的定义:

[defns.valid]

value of an object that is not specified except that the object's invariants are met and operations on the object behave as specified for its type

[ Example: If an object x of type std​::​vector is in a valid but unspecified state, x.empty() can be called unconditionally, and x.front() can be called only if x.empty() returns false. — end example ]

std::list 规范没有为移动构造函数添加进一步的保证。

不,您必须清除它,否则它会留在 "unspecified state" 中 - 根据 std::list

上的文档

也许值得解释为什么列表之后可能不为空。

如果移动最终成为副本,例如由于不兼容的分配器并且分配器未移动,则列表可能仍然包含旧元素。

尽管在所有情况下都(不一致地)要求清除向量,但委员会支持要求在兼容时将分配给向量的容量移回右侧操作数与分配器情况。