【问题标题】:Is it safe to call size() method on moved-from vector? [duplicate]在移动的向量上调用 size() 方法是否安全? [复制]
【发布时间】: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&amp;&amp; ) 的要求是 在一般情况下 ,缓冲区必须移动到目标向量,源向量不能保存任何东西,必须为空。但是,一个疯狂的 std 库可能能够证明做一些不同的事情是合理的,尤其是对于 POD 向量。
  • @Yakk-AdamNevraumont 所以vector(vector&amp;&amp; arg) 简单地调用相关的swap(*this, arg) 是非法的吗?它在哪里说移动的向量必须是空的?
  • @Fureeish 这不是operator=,它是移动构造。 “目标”向量中没有任何东西可以换出。可以(通常)观察到额外的分配;所以不可能发生。有很多疯狂的方法可以解决这个问题,但不是一般的。

标签: c++ c++17 stdvector move-semantics


【解决方案1】:

这里没有未定义的行为,因为缺少前置条件。该标准保证移出的容器将处于有效但未指定的状态。有效状态意味着可以调用任何没有前置条件的东西,但结果将是不可预测的。

是的,这不是 UB,但绝对没用而且是个坏主意。

【讨论】:

    猜你喜欢
    • 2012-10-24
    • 2020-06-27
    • 2020-01-21
    • 2016-10-07
    • 2011-09-21
    • 1970-01-01
    • 2021-06-05
    • 1970-01-01
    • 2012-12-07
    相关资源
    最近更新 更多