'[](std::list& list)<int>{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
为空吗?
No.从大多数标准库类移动会使它们处于"有效但未指定的状态" [1]。这意味着您必须显式清除a.list
以确保它在移动后为空。
[1] 此规则也有例外:最值得注意的是,std::unique_ptr
在移动后必须为 null。
上面的最后一行能保证将 a.list 留空吗?
不。该标准规定如下:
[lib.types.movedfrom]
C++标准库中定义的类型的对象可以从 ([class.copy.ctor]( 中移动。 移动操作可以显式指定或隐式生成。 除非另有说明,否则此类移出对象应处于有效但未指定的状态。
这是有效但未指定状态的定义:
[defns.valid]
未指定的对象的值,除非满足对象的不变量,并且对对象的操作的行为符合为其类型指定的操作
[ 示例:如果 std::vector 类型的对象 x 处于有效但未指定的状态,则可以无条件调用 x.empty((,并且只有在 x.empty(( 返回 false 时才能调用 x.front((。 — 结束示例 ]
std::list
规范没有为移动构造函数添加进一步的保证。
不,您必须清除它,否则它将处于"未指定状态" - 根据std::list
的文档
也许值得解释为什么列表之后可能不为空。
如果移动最终成为副本,例如由于不兼容的分配器并且分配器未移动,则列表可能仍具有旧元素。
虽然(不一致地(要求在所有情况下清除矢量,但委员会支持要求将分配给矢量的容量移回右侧操作数,而这符合分配器的情况。
相关文章:
- 使用std::multimap迭代器创建std::list
- 来自 std::list 的迭代器 .end() 按预期返回"0xcdcdcdcdcdcdcdcd"但 .begin()
- 使用"std::unordereded_map"映射到"std::list"对象
- 使用std::list创建循环链表
- '[](std::list& list)<int>{return std::move(list)}(list)' 是否保证将 'list' 留空?
- 如果 KEY 是 std::list 或 std::vector 而不是值,那么 std::map 的默认行为是什么?
- 为什么这个 std::queue/指向结构的指针列表直到 List.Size() == 0 才释放内存?
- "std::list::splice(std::const_iterator pos, std::list&& other)"是否保证将"其他"留空?
- 从嵌套循环中的 std::list 中删除将返回访问冲突
- 内存未释放 std::list<std::shared_ptr<std::string>> C++
- 像 std::list<std::p air<string, string>> 这样的结构在返回时会被复制吗?
- std::list<std::shared_ptr>::擦除得到了一个SIGSEGV
- 将 std::list<std::unique_ptr> 移动到向量中会尝试引用已删除的函数
- C++ DLL 返回指向 std::list<std::wstring 的指针>
- 您将如何为 std::list<std::string> 创建一个类型映射,以在<String> List in C++ 中为 Java 在 SWIG 中创建?
- std::list<std::unique_ptr>:空初始值设定项列表与默认构造函数
- 错误 C2440:"=":无法从"std::list<std::string,std::分配器<_Ty>> *'转换为"std::string*"
- 无法理解如何将新对象添加到 std::list<std::unique_ptr<classname>>
- std::list<std::future>析构函数不阻塞
- 无法反序列化 std::list<std::string>