std::vector::data()在移动时是否保留?

5

可能是重复的问题:
移动vector会使迭代器失效吗?

考虑以下代码:

std::vector<T> prepare(T*& data) {
    std::vector<T> buffer;
    // Fill in buffer.
    data = buffer.data();
    return buffer;
}

...

T* data;
auto vec = prepare(data);
// line 12

在第12行中,vec.data() != data是否可能出现?同样地,

std::vector<T> buffer;
// ... Fill in buffer ...
T* data = buffer.data();
auto vec = std::move(buffer);
// line 5

第5行中的vec.data() != data是否可能呢?在libstdc++和libc++的实现中,这两者实际上都是不可能的,因为移动构造函数被实现为简单的指针赋值。但似乎标准没有对此进行任何规定(类似于移动std::vector时是否需要保留容量?)。“常数复杂度”能保证vec.data() == data吗?


使迭代器/指针无效的事情已经相当明确地列举出来了。 - Ben Voigt
还有相关内容:https://dev59.com/K2855IYBdhLWcg3w0H93 - Ben Voigt
1个回答

0

常数复杂度意味着容器不允许复制/移动单个元素,因此必须将现有存储的所有权转移给新对象,因此data()返回的指针必须相同。

对于移动赋值(而不是移动构造),仅当向量的分配器类型的propagate_on_container_move_assignment为true或分配器相等时才成立。


一些疯狂的实现方式可以移动/复制常量数量的单个元素。 - zch
@zch:这违反了连续性要求。 - Ben Voigt
@BenVoigt,如果是这样的话 if(<10) copyAll(); else moveOwnership(); 怎么办? - zch
@zch:请查看我在此问题评论中链接的两个问题。 - Ben Voigt
1
@zch,这被称为“小对象优化”,但vector::swap()必须是无抛出异常的,这将禁用小对象优化。 - Jonathan Wakely

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接