删除std :: vector中间的元素仍然是昂贵的可移动类型?

Xeo*_*Xeo 10 c++ vector move-semantics c++11

通常认为删除a中间的元素std::vector是昂贵的,因为它需要复制后面的每个元素以填充空洞.

对于C++ 11,std::vector将改为所有元素向下移动,这应该非常快(如果仅与副本相关),至少我认为如此.当然它仍然是线性的,当然,它应该比旧版本更快.

这是真的吗?我不必担心在中间删除一些物体吗?

lar*_*moa 15

这取决于向量中的内容.如果它是POD或指针,我无法想象它会有任何区别.如果它的类实例很难复制,但可以非常快地移动,我希望用C++ 0x加速.

但是,我认为如果从std :: vectors中间删除元素是代码中的瓶颈,那么C++ 0x可能不是正确的修复方法.考虑数据结构,处理这样的情况下更好的代替,或者std::iter_swap再加上std::vector::pop_back如果元素的顺序并不重要.


Dav*_*eas 11

如果考虑到标准使用的成本,那将是非常昂贵的.标准规定了对包含类型执行的操作的成本,并且操作数量仍然相同,只是每个操作都会更快.

例如,在C++ 03中考虑在a中间插入元素的成本vector<string>.该标准调用O(N),其中N是向量的大小,但实际成本是O(N * M)其中M的字符串的大小.M在分析容器中的操作成本时忽略的原因在于它取决于所包含的元素.具有可移动类型的C++ 0x中的成本将是O(N)(字符串可以移动到新位置),但是广告的复杂性将O(N)在两种情况下都是如此.

对于一个简单的反例,如果你认为在向量中间插入是C++ 03中的一个昂贵的操作,并且你考虑std::vector<int>,那么插入C++ 0x中的向量中间同样昂贵,在这种情况下没有加速.

另请注意,任何潜在的改进都取决于您的对象是可移动的(它们不需要),并且某些当前的STL实现已经以类似的方式进行了优化(没有语言支持),例如,Dinkumware实现(我认为是这一个)有一些优化,当它std::vector<std::vector<T> >增长时,它会创建新的存储并使用向量进行初始化(没有分配的内存,因此成本最低),然后swap是旧的和新的向量分配区域,有效地实现移动语义.


Pup*_*ppy 6

实际上,在绝大多数情况下,移动比复制要快得多.任何具有通过引用存储的信息的类型都可以防止复制 - 例如,几乎所有容器,智能指针等,以及涉及这些类型的任何类.

当然这仍然是线性时间,所以如果你有一百万英镑,它就不会更快.但是,移动诸如容器和智能指针之类的东西比复制它们要快几个数量级.


Lig*_*ica 5

我仍然是C++ 0x移动内容的新手,但我无法真正看到你将如何在这里得到任何有用的加速vector.

它必须归结为你的元素类型:我无法想象你将获得任何加速,除非你的元素类型的对象移动比复制更快.

  • @DeadMG:如果向量很大,那么即使复制/移动每个元素都很便宜,从中间删除也会很昂贵. (2认同)