C++11 standard template (STL) std::vector (7)

Defined in the header file <vector>
template<

    class T,
    class Allocator = std::allocator<T>

> class vector;
(1)
namespace pmr {

    template <class T>
    using vector = std::vector<T, std::pmr::polymorphic_allocator<T>>;

}
(2) (since C++17)

 1) std::vectoris a sequential container that encapsulates a dynamic array.

2) std::pmr::vectoris a template alias that uses a polymorphic allocator.

Elements are stored sequentially, which means that elements can be accessed not only through iterators, but also with regular pointers to elements. This means that a pointer to a vector element can be passed to any function expecting a pointer to an array element.

(since C++03)

The storage of vector is managed automatically, expanding and shrinking on demand. A vector typically takes up more space than a static array because more memory is allocated to manage future growth. The way the vector is used is not to reallocate every time an element is inserted, but only when the extra memory is exhausted. The total amount of memory allocated can be queried with the capacity() function. Additional memory can be returned to the system through a call to shrink_to_fit(). (since C++11)

Reallocation is usually a performance-intensive operation. The reserve() function can be used to eliminate reallocation if the number of elements is known.

The complexity (efficiency) of common operations on vector is as follows:

  • Random access - constant O(1)
  • Insert or remove elements at the end - amortized constant O(1)
  • Insert or remove elements - O(n) linear in distance to end of vector

std::vector(For boolother T) Satisfy the requirements of Container , AllocatorAwareContainer , SequenceContainer , ContiguousContainer (since C++17) and ReversibleContainer .

capacity

reserved storage space

std::vector<T,Allocator>::reserve

void reserve( size_type new_cap );

 Increases the capacity of vector to a value greater than or equal new_capto . If new_capis greater than the current capacity(), new storage is allocated, otherwise this method does nothing.

reserve()The size of vector is not changed.

If new_capis greater than capacity(), all iterators, including post-end iterators and all references to elements are invalidated. Otherwise, no iterators or references are invalidated.

parameter

new_cap - the new capacity of vector
type requirements
-Must Tmeet the requirements for MoveInsertable .

return value

(none)

abnormal

  • std::length_error if new_cap > max_size().
  • Allocator::allocate()Any exception thrown by (typically std::bad_alloc)

If an exception is thrown, this function has no effect (strong exception guarantee).

If Tthe move constructor of is not noexcept and T is not CopyInsertable*this , then vector will use the move constructor. If it throws, the guarantee is discarded, and the effect is unspecified.

(since C++11)

the complexity

At most linear in size() of the container.

Notice

Not available reserve()Reduce container capacity. Provided for this purpose is shrink_to_fit().

Correct use reserve()can avoid unnecessary allocations, but inappropriate use reserve()(such as calling it before each push_back() call) may actually increase the number of reallocations (by causing the capacity to grow linearly rather than exponentially) and cause computational complexity increase, performance decreases.

Returns the number of elements that the current storage space can hold

std::vector<T,Allocator>::capacity

size_type capacity() const;

(until C++11)

size_type capacity() const noexcept;

(since C++11)

 Returns the number of elements the container has currently allocated space for.

parameter

(none)

return value

The capacity of the currently allocated storage.

the complexity

constant.

Reduce memory usage by freeing unused memory

std::vector<T,Allocator>::shrink_to_fit

void shrink_to_fit();

(since C++11)

 Request to remove unused capacity.

It is an optional request to reduce capacity() to size(). Whether the request is fulfilled is implementation dependent.

If reallocation occurs, all iterators, including post-end iterators, and all references to elements are invalidated. If no reallocation occurs, no iterators or references are invalidated.

parameter

(none)

type requirements
-Must Tmeet the requirements for MoveInsertable .

return value

(none)

the complexity

At most linear in container size.

Notice

Has no effect if an exception is thrown by an operation other than T's move constructor.

modifier

Change the number of elements that can be stored in the container

std::vector<T,Allocator>::resize

void resize( size_type count, T value = T() );

(until C++11)

void resize( size_type count );

(1) (since C++11)

void resize( size_type count, const value_type& value );

(2) (since C++11)

Resize container to countaccommodate elements.

If the current size is greater than count, reduce the container to its countfirst element.

If the current size is less than count, additional elements are appended, initialized valuewith a copy of .

(until C++11)

If the current size is less than count,

1) then appends an additional default inserted element

2) then append an additional copy valueof

(since C++11)

parameter

count - container size
value - the value to initialize the new element with
type requirements
- In order to use the overload (1), the requirements of MoveInsertable and DefaultInsertable must be Tmet .
- In order to use overload (2), the requirement of CopyInsertableT must be satisfied .

return value

(none)

the complexity

countLinear to the difference between the current size and . If the capacity is less than count, there may be additional complexity caused by reallocation.

abnormal

If an exception is thrown, this function has no effect (strong exception guarantee).

In overload (1), Tif the move constructor of is not noexcept and T is not CopyInsertable to *this, then vectorwill use the throwing move constructor. If it throws, the guarantee is discarded and the effect is unspecified.

(since C++11)

Notice

若不想要重载 (1) 中的值初始化,例如元素是非类类型且不需要清零,则可以提供定制的 Allocator::construct 避免。

在重设大小到较小值时, vector 的容量决不减少,因为这会非法化所有的,而非只非法化等价的 pop_back() 调用序列所非法化的迭代器。

调用示例

#include <iostream>
#include <string>
#include <iterator>
#include <algorithm>
#include <functional>
#include <time.h>
#include <vector>

using namespace std;

struct Cell
{
    int x;
    int y;

    Cell() = default;
    Cell(int a, int b): x(a), y(b) {}

    Cell &operator +=(const Cell &cell)
    {
        x += cell.x;
        y += cell.y;
        return *this;
    }

    Cell &operator +(const Cell &cell)
    {
        x += cell.x;
        y += cell.y;
        return *this;
    }

    Cell &operator *(const Cell &cell)
    {
        x *= cell.x;
        y *= cell.y;
        return *this;
    }

    Cell &operator ++()
    {
        x += 1;
        y += 1;
        return *this;
    }


    bool operator <(const Cell &cell) const
    {
        if (x == cell.x)
        {
            return y < cell.y;
        }
        else
        {
            return x < cell.x;
        }
    }

    bool operator >(const Cell &cell) const
    {
        if (x == cell.x)
        {
            return y > cell.y;
        }
        else
        {
            return x > cell.x;
        }
    }

    bool operator ==(const Cell &cell) const
    {
        return x == cell.x && y == cell.y;
    }
};

std::ostream &operator<<(std::ostream &os, const Cell &cell)
{
    os << "{" << cell.x << "," << cell.y << "}";
    return os;
}


int main()
{
    std::cout << std::boolalpha;

    std::mt19937 g{std::random_device{}()};
    srand((unsigned)time(NULL));

    auto generate = []()
    {
        int n = std::rand() % 10 + 110;
        Cell cell{n, n};
        return cell;
    };

    //3) 构造拥有 count 个有值 value 的元素的容器。
    std::vector<Cell> vector1(2, generate());
    //替换容器的内容。1) 以 count 份 value 的副本替换内容。
    std::cout << "vector1:  ";
    std::copy(vector1.begin(), vector1.end(), std::ostream_iterator<Cell>(std::cout, " "));
    std::cout << std::endl;
    std::cout << std::endl;

    //打印数组真实地址
    std::cout << "vector1.data():       " << vector1.data() << std::endl;
    //增加 vector 的容量到大于或等于 new_cap 的值。
    //若 new_cap 大于当前的 capacity() ,则分配新存储,否则该方法不做任何事。
    vector1.reserve(1);
    //打印数组真实地址
    std::cout << "vector1.data():       " << vector1.data() << std::endl;
    //返回容器当前已为之分配空间的元素数。
    std::cout << "vector1.capacity():   " << vector1.capacity() << std::endl;
    vector1.reserve(3);
    //打印数组真实地址
    std::cout << "vector1.data():       " << vector1.data() << std::endl;
    std::cout << "vector1.capacity():   " << vector1.capacity() << std::endl;
    std::cout << std::endl;

    //请求移除未使用的容量。它是减少 capacity() 到 size()非强制性请求。
    vector1.shrink_to_fit();
    std::cout << "vector1.data():       " << vector1.data() << std::endl;
    std::cout << "vector1.capacity():   " << vector1.capacity() << std::endl;
    std::cout << std::endl;


    //3) 构造拥有 count 个有值 value 的元素的容器。
    std::vector<Cell> vector2(5, {101, 101});
    //替换容器的内容。1) 以 count 份 value 的副本替换内容。
    std::cout << "vector2:  ";
    std::copy(vector2.begin(), vector2.end(), std::ostream_iterator<Cell>(std::cout, " "));
    std::cout << std::endl;

    //重设容器大小以容纳 count 个元素。
    //若当前大小大于 count ,则减小容器为其首 count 个元素。
    vector2.resize(3, {102, 102});
    std::cout << "vector2:  ";
    std::copy(vector2.begin(), vector2.end(), std::ostream_iterator<Cell>(std::cout, " "));
    std::cout << std::endl;
    //若当前大小小于 count ,则后附额外元素,并以 value 的副本初始化
    vector2.resize(5, {103, 103});
    std::cout << "vector2:  ";
    std::copy(vector2.begin(), vector2.end(), std::ostream_iterator<Cell>(std::cout, " "));
    std::cout << std::endl;
    //若当前大小小于 count ,1) 则后附额外的默认插入的元素
    vector2.resize(6);
    std::cout << "vector2:  ";
    std::copy(vector2.begin(), vector2.end(), std::ostream_iterator<Cell>(std::cout, " "));
    std::cout << std::endl;

    return 0;
}

Guess you like

Origin blog.csdn.net/qq_40788199/article/details/130462941