【发布时间】:2019-11-22 07:22:35
【问题描述】:
标准指定 STL 容器在开始 moved 之后(在这种情况下,我们讨论的是启用移动构造/分配的 std::move),有效,但 未指定 状态。
我相信这意味着我们只能应用不需要先决条件的操作。我记得有人在 Stackoverflow 上声称这是真的,经过一番检查后我同意了。不幸的是,我不记得我检查了哪些来源。此外,我无法在标准中找到相关信息。
从[container.requirements.general/4],表62([tab:container.req])可以看出a.size()没有前置条件。这是否意味着这段代码是安全的?
#include <iostream>
#include <vector>
int main() {
std::vector<int> v1 = {1, 2, 3};
std::vector<int> v2 = std::move(v1);
std::cout << v1.size(); // displaying size of the moved-from vector
}
未指定此代码将打印什么,但它是否安全?意思是,我们这里有未定义的行为吗?
编辑:如果我询问其他容器,我认为这个问题不会太宽泛。 所有其他 STL 容器(包括 std::string)的答案是否一致?
【问题讨论】:
-
查看标准容器函数/操作的先决条件:timsong-cpp.github.io/cppwp/container.requirements
-
顺便说一句,
.size()除了0之外没有任何实用的方法可以返回:vector( vector&& )的要求是 在一般情况下 ,缓冲区必须移动到目标向量,源向量不能保存任何东西,必须为空。但是,一个疯狂的 std 库可能能够证明做一些不同的事情是合理的,尤其是对于 POD 向量。 -
@Yakk-AdamNevraumont 所以
vector(vector&& arg)简单地调用相关的swap(*this, arg)是非法的吗?它在哪里说移动的向量必须是空的? -
@Fureeish 这不是
operator=,它是移动构造。 “目标”向量中没有任何东西可以换出。可以(通常)观察到额外的分配;所以不可能发生。有很多疯狂的方法可以解决这个问题,但不是一般的。
标签: c++ c++17 stdvector move-semantics