【C++】STL vector容器之assign方法
前言
vector的成员assign方法,负责分配新的内容至vector中,以代替现有的内容并相应的修改其size。在c++11的标准中有三种调用方式,以下分别介绍。
一、Range用法
void assign (InputIterator first, InputIterator last);
range版本是迭代器调用版本,新内容是由 first 和 last 范围内的每个元素以相同的顺序构造的。使用的范围是 [first,last)
代码如下(示例):
// vector assign
#include <iostream>
#include <vector>
#include <string>
using namespace std;
int main()
{
std::vector<double> first{ 1.9, 2.9, 3.9, 4.9, 5.9 }; /*初始化源数组*/
std::vector<double> second; /*声明空数组*/
std::vector<int> third;
std::vector<string> forth;
std::vector<double>::iterator it;
it = first.begin();
second.assign(it, first.end());
std::cout << "Size of second: " << int(second.size()) << '\n';
for (int i = 0; i < second.size(); i++)
cout << second[i] << " ";
cout << endl;
//结果:
//Size of second: 5
//1.9 2.9 3.9 4.9 5.9
second.assign(it + 1, first.end() - 1);
std::cout << "Size of second: " << int(second.size()) << '\n';
for (int i = 0; i < second.size(); i++)
cout << second[i] << " ";
cout << endl;
//Size of second: 3
//2.9 3.9 4.9
third.assign(it, first.end());
std::cout << "Size of third: " << int(third.size()) << '\n';
for (int i = 0; i < third.size(); i++)
cout << third[i] << " ";
cout << endl;
//Size of third: 5
//1 2 3 4 5
int myints[] = {1776,7,4};
third.assign (myints,myints+3); /* assign with array*/
std::cout << "Size of third: " << int(third.size()) << '\n';
for (int i = 0; i < third.size(); i++)
cout << third[i] << " ";
cout << endl;
//Size of third: 3
//1776 7 4
//third.assign (myints,myints+4); /*error usage,有结果但是行为错误*/
//1776 7 4 787800
// third = first; /*error usage*/
// forth.assign(it,first.end()); /*error usage*/
return 0;
}
可以看出range版本的assign方法类似于 operator=,就是依据迭代器指示的范围赋值内容并相应地改变目的容器尺寸。并且指针也是迭代器,所以当然也支持 assign with array,但是注意迭代器其范围不能超过array的size,否则范围外的内容是未定义的。
需要注意的是:assign是支持类型转换的,这一点与operator=不同
二、Fill用法
void assign (size_type n, const value_type& val);
fill版本:用 n 个值为 val 的元素填充目的容器
代码如下(示例):
// vector assign
#include <iostream>
#include <vector>
using namespace std;
int main()
{
std::vector<int> first(7); /*fill版构造,无初值*/
std::vector<int> second(7,1); /*fill版构造,给定初值*/
std::vector<int> third;
third.assign(7,2); /*fill版 assign */
std::vector<int> forth;
//forth.assign(7); /*error usage, fill版assign必须给初值*/
for (int i = 0; i < first.size(); i++)
cout << first[i] << " ";
cout << endl;
for (int i = 0; i < second.size(); i++)
cout << second[i] << " ";
cout << endl;
for (int i = 0; i < third.size(); i++)
cout << third[i] << " ";
cout << endl;
//结果:
//0 0 0 0 0 0 0
//1 1 1 1 1 1 1
//2 2 2 2 2 2 2
return 0;
}
可以看出fii版的assign方法与fill版的构造方法十分类似,不同的是构造方法支持无初值版本,使用默认值构造,但是assign方法必须给出 val 值。
三、initializer list用法
void assign (initializer_list<value_type> il);
initializer list版本就是C++ 11的新特性初始化列表的应用,也比较好理解
代码如下(示例):
/#include <iostream>
#include <vector>
using namespace std;
int main()
{
std::vector<double> first{ 1.9, 2.9, 3.9, 4.9, 5.9 }; /*初始化源数组*/
std::vector<double> second; /*声明空数组*/
second.assign({1.5,2,5,3.5});
std::cout << "Size of first: " << int(first.size()) << '\n';
for (int i = 0; i < first.size(); i++)
cout << first[i] << " ";
cout << endl;
//结果:
//Size of first: 5
//1.9 2.9 3.9 4.9 5.9
std::cout << "Size of second: " << int(second.size()) << '\n';
for (int i = 0; i < second.size(); i++)
cout << second[i] << " ";
cout << endl;
//结果:
//Size of second: 4
//1.5 2 5 3.5
return 0;
}
总结
以上就是STL库中vector容器的assign方法的三种调用方法,调用之前保存在容器中的任何元素都将被销毁,并被新构造的元素替换(不发生元素赋值)。
此外,assign方法将导致分配的存储空间自动重新分配,当且仅当新vector 的size超过当前vector的capacity。注意 size和capacity的区别。