令C表示六个顺序容器类型期中之一(vector,deque,list,forward,string,array),以下详细说明定义和初始化以及赋值.
1.容器定义和初始化
(1)C c;默认构造函数,如果c是一个array,则c中元素按照默认初始化;否则c为空。
解释:默认初始化,如果c是全局变量,int 初始化为0,如果c是局部变量。那么初始化为任意整数值。string 对象全部初始化为空串子.
(2)C c1(c2) ; c1初始化为c2的类型。c1 和c2必须是同类型的constainer.对于array,c1和c2必须长度相同.注意这是初始化。离开定义是不能这样使用的。例如:下面就是错误的,因为初始化时候才能用圆括号。
vector<int> v_int1 = {1,2,3,4,5,6},v_int2;
v_int2(v_int1);
(3)C c1 = c2; 定义c1,并且把c2的赋给c1.包括定义和赋值两个过程。
(4)C c1{a,b,c,d,e,f};把c1列表初始化为花括号内的部分。
(5)C c1 = {a,b,c,d,e,f};把c1列表初始化为花括号内的拷贝。
(6)C c1(b,e);b和e为两个迭代器类型.
(7)C seq(n); seq包含n个元素,这些元素进行了值初始化;此构造函数是explict的。(string不适用).
看下面的c11,d11,l11,f11四个对象。string不适用。
#include <iostream>
#include <string>
#include <vector>
#include <deque>
#include <list>
#include <forward_list>
#include <string>
#include <array>
using namespace std;
#define LENGTH 10
typedef int TYPE;
typedef vector<TYPE> VECTORTYPE;
typedef deque<TYPE> DEQUETYPE;
typedef list<TYPE> LISTTYPE;
typedef forward_list<TYPE> FORWARD_LISTTYPE;
typedef array<TYPE,LENGTH> ARRAYTYPE;
void print(auto &);
ARRAYTYPE a;
int main()
{
//test C c(b,e);
VECTORTYPE v_type{1,2,3,4,5,6},v_type2;
VECTORTYPE v_type1(v_type.begin() + 1 ,v_type.end() -1);
VECTORTYPE c11(LENGTH);
DEQUETYPE d11(LENGTH);
LISTTYPE l11(LENGTH);
FORWARD_LISTTYPE f11(LENGTH);
print(c11);
print(d11);
print(l11);
print(f11);
return 0;
}
void print(auto &vec)
{
for(auto i = vec.begin() ; i != vec.end() ; ++i)
{ cout << *i << " ";}
cout << endl;
return ;
}
如果string对象用,如下:
string s(10);
编译器报错如下:
11.cc:30:14: error: invalid conversion from ‘int’ to ‘const char*’ [-fpermissive]
string s(10);
(8)C seq(n,t),包含n个t值。array不满足,array<int,10>,有本身的固定类型和长度。
例如:
string s(10,'a');//定义string对象s为10个a
#include <iostream>
#include <string>
#include <vector>
#include <deque>
#include <list>
#include <forward_list>
#include <string>
#include <array>
using namespace std;
#define LENGTH 10
typedef int TYPE;
typedef vector<TYPE> VECTORTYPE;
typedef deque<TYPE> DEQUETYPE;
typedef list<TYPE> LISTTYPE;
typedef forward_list<TYPE> FORWARD_LISTTYPE;
typedef array<TYPE,LENGTH> ARRAYTYPE;
void print(auto &);
ARRAYTYPE a;
int main()
{
//test C c(b,e);
VECTORTYPE v_type{1,2,3,4,5,6},v_type2;
VECTORTYPE v_type1(v_type.begin() + 1 ,v_type.end() -1);
VECTORTYPE c11(LENGTH,4);
DEQUETYPE d11(LENGTH,5);
LISTTYPE l11(LENGTH,6);
FORWARD_LISTTYPE f11(LENGTH,7);
print(c11);
print(d11);
print(l11);
print(f11);
return 0;
}
void print(auto &vec)
{
for(auto i = vec.begin() ; i != vec.end() ; ++i)
{ cout << *i << " ";}
cout << endl;
return ;
}
note1:标准库array大小:
(1)array<int,10> arr_int{1,2,3,4,5,6,7,8,9,0};
array<int,10>::size_type i; //right
array<int>::size_type j;//wrong
结论:array的大小是array定义的一部分,array不支持普通的容器构造函数。普通构造函数都会确定容器大小,所以及其容易出错。
array<int,10> arr_int1{1,2,3,4,5,6,7,8,9,0};
array<int,10> arr_int2;
array<int,10> arr_int3{1024};
cout << endl;
print_array(arr_int1);
print_array(arr_int2);
print_array(arr_int3);
三个array对象打印如下,说明局部数组的元素的任意随机整数值。
1 2 3 4 5 6 7 8 9 0
0 121 65535 1 -1240874352 32766 993197120 22013 2 0
1024 0 0 0 0 0 0 0 0 0
(2)
array<int,10> arr_int1{1,2,3,4,5,6,7,8,9,0};
array<int,10> arr_int2;
array<int,10> arr_int3{1024};
array<int,10> arr_int4(arr_int2),arr_int5=arr_int1;//array可以拷贝,或者=赋值
补充1.创建一个容器为另一个容器的拷贝,那么容器类型和元素类型必须匹配。不过,当传递参数是一个迭代器范围时,就不需要容器类型是相同的了。而且,新容器和原容器的元素类型也可以不同,只要能够将要拷贝的元素转换为要初始化的容器的元素类型即可。如下面表1和表2(注意char*可以直接转化成string,反过来必须借助c函数例如c_str(),data成员函数)
//表1
#include <iostream>
#include <string>
#include <vector>
#include <deque>
#include <list>
#include <forward_list>
#include <string>
#include <array>
using namespace std;
#define LENGTH 10
typedef string TYPE;
typedef vector<TYPE> VECTORTYPE;
typedef deque<TYPE> DEQUETYPE;
typedef list<TYPE> LISTTYPE;
typedef forward_list<TYPE> FORWARD_LISTTYPE;
typedef array<TYPE,LENGTH> ARRAYTYPE;
void print(auto &);
ARRAYTYPE a;
int main()
{
list<string> authors = {"Milton","Shakespeare","Austen"};
vector<const char*> articles = {"a","an","the"};
vector<char*> articles_2(authors); //wrong,type is not same
list<string> list2(authors); //right
deque<string> authList(authors); //wrong,type is not same
vector<string> words(articles); //wrong,type is not same
return 0;
}
void print(auto &vec)
{
for(auto i = vec.begin() ; i != vec.end() ; ++i)
{ cout << *i << " ";}
cout << endl;
return ;
}
11.cc:24:35: error: no matching function for call to ‘std::vector<char*>::vector(std::__cxx11::list<std::__cxx11::basic_string<char> >&)’
vector<char*> articles_2(authors); //wrong,type is not same
11.cc:26:33: error: no matching function for call to ‘std::deque<std::__cxx11::basic_string<char> >::deque(std::__cxx11::list<std::__cxx11::basic_string<char> >&)’
deque<string> authList(authors); //wrong,type is not same
11.cc:27:32: error: no matching function for call to ‘std::vector<std::__cxx11::basic_string<char> >::vector(std::vector<const char*>&)’
vector<string> words(articles); //wrong,type is not same
//表2是 表1修正后的代码
#include <iostream>
#include <string>
#include <vector>
#include <deque>
#include <list>
#include <forward_list>
#include <string>
#include <array>
using namespace std;
#define LENGTH 10
typedef string TYPE;
typedef vector<TYPE> VECTORTYPE;
typedef deque<TYPE> DEQUETYPE;
typedef list<TYPE> LISTTYPE;
typedef forward_list<TYPE> FORWARD_LISTTYPE;
typedef array<TYPE,LENGTH> ARRAYTYPE;
void print(auto &);
ARRAYTYPE a;
int main()
{
list<string> authors = {"Milton","Shakespeare","Austen"};
vector<const char*> articles = {"a","an","the"};
vector<char*> articles_2(authors.begin(),authors.end()); //wrong,string 不能直接转化成char*
list<string> list2(authors);
//采用了迭代器初始化,容器类型和元素类型可以不同了。只要元素类型可以转化就ok
deque<string> authList(authors.begin(),authors.end());
// 同上
vector<string>words(articles.begin(),articles.end());
return 0;
}
void print(auto &vec)
{
for(auto i = vec.begin() ; i != vec.end() ; ++i)
{ cout << *i << " ";}
cout << endl;
return ;
}
11.cc:24:57: required from here
/usr/include/c++/7/bits/stl_construct.h:75:7: error: cannot convert ‘std::__cxx11::basic_string<char>’ to ‘char*’ in initialization
{ ::new(static_cast<void*>(__p)) _T1(std::forward<_Args>(__args)...); }