简体   繁体   English

专门研究 std::vector 如何增长

[英]Specialize how std::vector grows

It is recommended by the C++ standard that std::vector grows exponentially in order to have an "amortized constant cost" regarding reallocation. C++ 标准建议 std::vector 呈指数增长,以便在重新分配方面具有“摊销恒定成本”。

Although this type of growth is suitable for most scenarios, there may be a situation where I found I need vector to grow using a different algorithm.虽然这种类型的增长适用于大多数场景,但可能有一种情况我发现我需要使用不同的算法来增长向量。

Is there a way to customize how std::vector grows and what conditions it checks before re-allocating?有没有办法自定义 std::vector 如何增长以及在重新分配之前检查什么条件?

This depends on what you mean by "customize std::vector ".这取决于“自定义std::vector ”的含义。 The requirements on std::vector allow you to do what you want. std::vector的要求允许你做你想做的事。 However, you can only do that inside an implementation of std::vector , which requires you to be writing a compiler, or standard library implementation.但是,您只能在std::vector实现中执行此操作,这需要您编写编译器或标准库实现。

In user code, you are not allowed to write anything into std , or at least you can't modify the behavior of std::vector directly.在用户代码中,您不允许将任何内容写入std ,或者至少您不能直接修改std::vector的行为。

You can still achieve the desired behavior by manually managing a std::vector to do exactly what you want.您仍然可以通过手动管理std::vector来实现所需的行为,以完全按照您的意愿行事。 Another option is to write your own user::vector class that has the desired behavior.另一种选择是编写您自己的具有所需行为的user::vector class。

Just like HolyBlackCat's comment, you can't change it.就像 HolyBlackCat 的评论一样,您无法更改它。 There is the part of code of STL vector implementation which from VC++.有来自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
}

No you cannot.你不能。 The standard library containers are precisely standard .标准库容器是完全标准的。 That means that:这意味着:

  • they are not intended to be subclassed它们不打算被子类化
  • you are not allowed to write your own version of std::vector because the std namespace is reserved您不能编写自己的std::vector版本,因为std命名空间是保留的

That being said, writing a custom dynamic array is not that hard.话虽如此,编写自定义动态数组并不难。 And it is probably the way to go if you only need simple access modes.如果您只需要简单的访问模式,这可能是 go 的方式。 The hard part comes when you expect it to be usable with all of the standard library goodies, like algorithms or ranged-base for loop.当您希望它可以与所有标准库的好东西一起使用时,困难的部分就来了,比如算法或基于范围的 for 循环。 Here again nothing is really hard but it will take quite a good deal of time and lines of code to implement the traits and iterators.再一次,没有什么是真正困难的,但是实现特征和迭代器需要相当多的时间和代码行。 Furthermore, while you only use standard containers, everything is guaranteed to work fine: the standard library provide special processing for its own inconsistencies like vector<bool> which otherwise would not respect the requirements of a container (a vector<bool> iterator does not iterate over bool objects).此外,虽然您只使用标准容器,但可以保证一切正常:标准库为其自身的不一致性提供特殊处理,例如vector<bool>否则将不尊重容器的要求( vector<bool>迭代器不迭代bool对象)。 But no hooks are provided for user written containers.但是没有为用户编写的容器提供挂钩。

Hopefully, if you only want to change the way a vector grows, you should not fall in any caveat or corner case.希望,如果您只想改变向量的增长方式,您不应该陷入任何警告或极端情况。 Simply implementing everything from scratch is a rather heavy way, and duplicating the standard library code to only change some part is at least brave, because the code base to read and understand is huge.简单地从头开始实现所有内容是一种相当繁重的方式,复制标准库代码以仅更改某些部分至少是勇敢的,因为要阅读和理解的代码库是巨大的。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM