c++ 11标准模板(STL) std::vector (二)

访问首尾元素

首元素

reference front();		// 可读写
const_reference front() const; //   可读,不可写

返回到容器首元素的引用。
在空容器上对 front 的调用是未定义的。
参数 (无)
返回值 到首元素的引用
复杂度 常数
注意 对于容器 c ,表达式 c.front() 等价于 *c.begin() 。

尾元素

reference back();					// 可读写
const_reference back() const;		//   可读,不可写

返回到容器中最后一个元素的引用。
在空容器上对 back 的调用是未定义的。
参数 (无)
返回值 到最后元素的引用。
复杂度 常数。
注意 对于容器 c ,表达式 return c.back(); 等价于 { auto tmp = c.end(); --tmp; return *tmp; }

用例

    std::vector<std::string> words1 {"I", "am", "the", "most", "handsome", "programmer"};
    // 返回到容器首元素的引用
    std::cout << "words1: " << "front() : " << words1.front() << endl;
    //  修改值
    words1.front() = "you";
    std::cout << "words1: " << "front() : " << words1.front() << endl;

    // 返回到容器中最后一个元素的引用
    std::cout << "words1: " << "back() : " << words1.back() << endl;
    words1.back() = "human";
    std::cout << "words1: " << "back() : " << words1.back() << endl;

容量


size_type capacity() const;			//	(C++11 前) 
size_type capacity() const noexcept;	//(C++11 起) 

参数 (无)
返回值 当前分配存储的容量。
复杂度 常数。

元素数量

返回容器中的元素数,即 std::distance(begin(), end()) 。
参数 (无)
返回值 容器中的元素数量。
复杂度 常数。

移除未使用的容量

void shrink_to_fit();			//	(C++11 起) 

请求移除未使用的容量。
它是减少 capacity() 到 size()非强制性请求。请求是否达成依赖于实现。
若发生重分配,则所有迭代器,包含尾后迭代器,和所有到元素的引用都被非法化。若不发生重分配,则没有迭代器或引用被非法化。
参数 (无)
类型要求 T 必须满足可移动插入 (MoveInsertable) 的要求。
返回值 (无)
复杂度 至多与容器大小成线性。
注意 若 T 移动构造函数以外的操作抛出异常,则无效果。

    std::vector<std::string> words {"I", "am", "the", "most", "handsome", "programmer"};
    std::cout << "words :" << "capacity(): " << words.capacity() << std::endl;
    std::cout << "wordswordswords :" << "size(): " << words.size() << std::endl;

    words.push_back("GGX");
    std::cout << "words :" << "capacity(): " << words.capacity() << std::endl;
    std::cout << "words :" << "size(): " << words.size() << std::endl;

    //请求移除未使用的容量
    words.shrink_to_fit();
    std::cout << "words1 :" << "capacity(): " << words.capacity() << std::endl;
    std::cout << "words1 :" << "size(): " << words.size() << std::endl;

重新分配容量

void reserve( size_type new_cap );

增加 vector 的容量到大于或等于 new_cap 的值。若 new_cap 大于当前的 capacity() ,则分配新存储,否则该方法不做任何事。
reserve() 不更改 vector 的 size 。
若 new_cap 大于 capacity() ,则所有迭代器,包含尾后迭代器和所有到元素的引用都被非法化。否则,没有迭代器或引用被非法化。
参数 new_cap - vector 的新容量
类型要求 T 必须满足可移动插入 (MoveInsertable) 的要求。
返回值 (无)
异常
若 new_cap > max_size() 则为 std::length_error 。
任何 Allocator::allocate() 所抛的异常(典型为 std::bad_alloc )
若抛出异常,则此函数无效果(强异常保证)。
若 T 的移动构造函数不是 noexcept 且 T 非可复制插入 (CopyInsertable) 到 *this ,则 vector 将使用移动构造函数。若它抛出,则摒弃保证,且效果未指定。(C++11 起)
复杂度 至多与容器的 size() 成线性。
注意 不能用 reserve() 减少容器容量。为该目的提供的是 shrink_to_fit() 。
正确使用 reserve() 能避免不必要的分配,但不适当地使用 reserve() (例如在每次 push_back() 调用前调用它)可能会实际增加重分配的数量(通过导致容量线性而非指数增长)并导致计算复杂度增加,性能下降。

修改可容纳元素数量


void resize( size_type count, T value = T() );			//	(C++11 前) 
void resize( size_type count );							// (1) (C++11 起) 
void resize( size_type count, const value_type& value );// (2) (C++11 起) 

重设容器大小以容纳 count 个元素。
若当前大小大于 count ,则减小容器为其首 count 个元素。
若当前大小小于 count ,则后附额外元素,并以 value 的副本初始化。 (C++11 前)
若当前大小小于 count ,

  1. 则后附额外的默认插入的元素
  2. 则后附额外的 value 的副本 (C++11 起)
    参数
    count - 容器的大小
    value - 用以初始化新元素的值
    类型要求
    为使用重载 (1) , T 必须满足可移动插入 (MoveInsertable) 和 可默认插入 (DefaultInsertable) 的要求。
    为使用重载 (2) , T 必须满足可复制插入 (CopyInsertable) 的要求。
    返回值(无) 复杂度
    与当前大小和 count 间的差成线性。若容量小于 count 则可能有重分配所致的额外复杂度。
    异常 若抛出异常,则此函数无效果(强异常保证)。
    重载 (1) 中,若 T 的移动构造函数不是 noexcept 且 T 不可复制插入 (CopyInsertable) 到 *this ,则 vector 将使用会抛出的移动构造函数。若它抛出,则抛弃保证且效果未指定。 (C++11 起)
    注意 若不想要重载 (1) 中的值初始化,例如元素是非类类型且不需要清零,则可以提供定制的 Allocator::construct 避免。
    在重设大小到较小值时, vector 的容量决不减少,因为这会非法化所有的,而非只非法化等价的 pop_back() 调用序列所非法化的迭代器。

用例

 	std::vector<std::string> words {"I", "am", "the", "most", "handsome", "programmer"};
    printVector("words : ", words);

    //若当前大小大于 count ,则减小容器为其首 count 个元素。
    std::vector<std::string> words1(words);
    std::cout << "words1 size : " << words1.size() << std::endl;
    words1.resize(words1.size() -1);
    std::cout << "words1 resize : " << words1.size() <<std::endl;
    printVector("words resize after: ", words1);

    // 若当前大小小于 count ,则后附额外元素,并以 value 的副本初始化
    std::vector<std::string> words2(words);
    std::cout << "words2 size : " << words2.size() << std::endl;
    words2.resize(words2.size() + 1, "handsome");
    std::cout << "words2 resize : " << words2.size() <<std::endl;
    printVector("words resize after: ", words2);

代码汇总

#include <vector>
#include <iostream>
using namespace std;

template<typename T>
void printVector(const string &name, const std::vector<T>& vec)
{
    std::cout << name << " : " ;
    for(auto &a :vec)
    {
        std::cout << a << " ";
    }
    std::cout << endl;
}

// 构造函数
void structure()
{
    std::cout << "structure start" << endl;
    // c++11 初始化器列表语法:
    std::vector<std::string> words1 {"I", "am", "the", "most", "handsome", "programmer"};
    printVector("words1", words1);

    // 构造拥有范围 [first, last) 内容的容器
    // words2 = words1
    std::vector<std::string> words2(words1.begin(), words1.end());
    printVector("words2", words2);

    // 拷贝构造 words3 = words1
    std::vector<std::string> words3(words1);
    printVector("words3", words3);

    // 构造拥有 count 个有值 value 的元素的容器
    //  words4 为 {"handsome", "handsome", "handsome", "handsome", "handsome"}
    std::vector<std::string> words4(5, "handsome");
    printVector("words4", words4);

    // 赋值构造
    std::vector<std::string> words5 = words3;
    printVector("words5", words5);

    std::cout << "structure end" << endl << endl;
}

void assign()
{
    std::cout << "assign start" << endl;

    // 以 count 份 value 的副本替换内容。
    std::vector<std::string> words1 {"I", "am", "the", "most", "handsome", "programmer"};
    printVector("words1_f", words1);
    words1.assign(5, "handsome");
    printVector("words1_s", words1);

    //以范围 [first, last) 中元素的副本替换内容。若任一参数是指向 *this 中的迭代器则行为未定义
    std::vector<std::string> words2;
    words2.assign(words1.begin(), words1.end());
    printVector("words2", words1);

    std::cout << "assign end" << endl << endl;
}

void at()
{
    std::cout << "at start" << endl;

    std::vector<std::string> words1 {"I", "am", "the", "most", "handsome", "programmer"};
    size_t size = words1.size();
    std::cout << "words1: ";
    for(size_t i = 0; i < size; i++)
    {
        std::cout << words1.at(i) << " ";
    }
    std::cout << endl;

    std::cout << "words1: ";
    for(size_t i = 0; i < size; i++)
    {
        std::cout << words1[i] << " ";
    }
    std::cout << endl;
    std::cout << "at end" << endl << endl;
}

void front_back()
{
    std::cout << "front_back start " << endl;
    std::vector<std::string> words1 {"I", "am", "the", "most", "handsome", "programmer"};
    // 返回到容器首元素的引用
    std::cout << "words1: " << "front() : " << words1.front() << endl;
    //  修改值
    words1.front() = "you";
    std::cout << "words1: " << "front() : " << words1.front() << endl;

    // 返回到容器中最后一个元素的引用
    std::cout << "words1: " << "back() : " << words1.back() << endl;
    words1.back() = "human";
    std::cout << "words1: " << "back() : " << words1.back() << endl;
    std::cout << "front_back end" << endl << endl;
}

void MYiterator()
{
    std::cout << "MYiterator start " << endl;
    std::vector<std::string> words1 {"I", "am", "the", "most", "handsome", "programmer"};
    for(std::vector<std::string>::const_iterator it = words1.cbegin(); it != words1.cend(); it ++)
    {
        std::cout << *it << " ";
    }
    std::cout << std::endl;

    for(std::vector<std::string>::const_reverse_iterator it = words1.crbegin(); it != words1.crend(); it ++)
    {
        std::cout << *it << " ";
    }
    std::cout << std::endl;
    std::cout << "MYiterator end" << endl << endl;
}

void capacity_size()
{
    std::cout << "capacity_size start " << endl;
    std::vector<std::string> words {"I", "am", "the", "most", "handsome", "programmer"};
    std::cout << "words :" << "capacity(): " << words.capacity() << std::endl;
    std::cout << "wordswordswords :" << "size(): " << words.size() << std::endl;

    words.push_back("GGX");
    std::cout << "words :" << "capacity(): " << words.capacity() << std::endl;
    std::cout << "words :" << "size(): " << words.size() << std::endl;

    //请求移除未使用的容量
    words.shrink_to_fit();
    std::cout << "words1 :" << "capacity(): " << words.capacity() << std::endl;
    std::cout << "words1 :" << "size(): " << words.size() << std::endl;
    std::cout << "capacity_size end" << endl << endl;
}

void MYResize()
{
    std::cout << "MYResize start " << endl;
    std::vector<std::string> words {"I", "am", "the", "most", "handsome", "programmer"};
    printVector("words : ", words);

    //若当前大小大于 count ,则减小容器为其首 count 个元素。
    std::vector<std::string> words1(words);
    std::cout << "words1 size : " << words1.size() << std::endl;
    words1.resize(words1.size() -1);
    std::cout << "words1 resize : " << words1.size() <<std::endl;
    printVector("words resize after: ", words1);

    // 若当前大小小于 count ,则后附额外元素,并以 value 的副本初始化
    std::vector<std::string> words2(words);
    std::cout << "words2 size : " << words2.size() << std::endl;
    words2.resize(words2.size() + 1, "handsome");
    std::cout << "words2 resize : " << words2.size() <<std::endl;
    printVector("words resize after: ", words2);
    std::cout << "MYResize end" << endl << endl;
}

int main( )
{
//    structure();
//    assign();
//    at();
    front_back();
//    MYiterator();
    capacity_size();
    MYResize();
    return 0;
}

c++ 11标准模板(STL) std::vector (二)

上一篇:最详细STL(四)priority_queue


下一篇:STL 概览