提问者:小点点

专门化STD::Vector是如何增长的


C++标准建议std::vector按指数增长,以便有一个关于重新分配的“摊余不变成本”。

虽然这种类型的增长适用于大多数场景,但可能存在这样一种情况,即我发现我需要使用不同的算法来增长vector。

有没有一种方法可以自定义std::vector是如何增长的,以及它在重新分配之前检查什么条件?


共3个答案

匿名用户

这取决于您所说的“自定义std::vector”是什么意思。 std::vector上的需求允许您做您想做的事情。 但是,您只能在std::vector的实现中这样做,这要求您编写编译器或标准库实现。

在用户代码中,不允许向std中写入任何内容,或者至少不能直接修改std::vector的行为。

您仍然可以通过手动管理std::vector来实现所需的行为。 另一种选择是编写具有所需行为的自己的User::Vector类。

匿名用户

就像HolyBlackcat的评论一样,你不能改变它。 最后给出了用VC++实现STL矢量的部分代码。

size_type _Calculate_growth(const size_type _Newsize) const {
    // given _Oldcapacity and _Newsize, calculate geometric growth
    const size_type _Oldcapacity = capacity();

    if (_Oldcapacity > max_size() - _Oldcapacity / 2) {
        return _Newsize; // geometric growth would overflow
    }

    const size_type _Geometric = _Oldcapacity + _Oldcapacity / 2;

    if (_Geometric < _Newsize) {
        return _Newsize; // geometric growth would be insufficient
    }

    return _Geometric; // geometric growth is sufficient
}

匿名用户

不,你不能。 标准库容器完全是标准的。 这意味着:

  • 不打算对它们进行子类化
  • 您不允许编写自己版本的std::vector,因为std命名空间是保留的

也就是说,编写一个自定义的动态数组并不是那么难。 而且如果您只需要简单的访问模式,这可能是一条可行的路。 当您期望它与所有标准库的优点(如算法或循环的范围基)一起使用时,困难的部分就来了。 这里也没有什么是真正困难的,但是实现traits和迭代器需要相当多的时间和代码行。 此外,虽然您只使用标准容器,但一切都可以保证正常工作:标准库为其自身的不一致性提供特殊处理,如vector,否则这些不符合容器的要求(vector迭代器不会迭代bool对象)。 但没有为用户编写的容器提供钩子。

希望,如果你只想改变向量增长的方式,你不应该陷入任何警告或角落的情况。 简单地从头实现一切是一种相当繁重的方式,而复制标准库代码只更改某一部分至少是勇敢的,因为需要阅读和理解的代码库是巨大的。