目录
四、initializer_list 包含头文件initializer_list
一、集合 包含头文件set
set:集合
1、数据自带排序
2、数据唯一性
(1)单集合
数据唯一会去重,无法插入重复数据,自带排序
void testSet()
{
//set<int> setData = { 1,3,8,4,2 };
srand((unsigned int)time(nullptr));//需要包含头文件ctime
set<int> setData;//可以省略排序准则,使用默认的的
//默认的方式:set<int, less<int>> setData2;
//从大到小:set<int, greater<int>> setData3;
for (int i = 0;i < 10;i++)
{//insert插入
setData.insert(rand() % 10);
}//默认从小到大排序
for (set<int>::iterator iter = setData.begin();iter != setData.end();iter++)
{
cout << *iter << " ";
}
}
(2)多重集合(没有去重功能,只有排序功能)
void testmultiset()
{
multiset<int> mulData;
for (int i = 0;i < 10;i++)
{
mulData.insert(rand() % 10);
}
for (auto v : mulData)
{
cout << v << " ";
}
}
(3)自定义数据插入
class MM
{
public:
MM(string name, int age) :name(name), age(age) {}
bool operator<(const MM& object)const
{
return this->name < object.name;
}
void print()
{
cout << name << " " << age << endl;
}
protected:
string name;
int age;
};
void testUserData()
{//写自己的比较准则 重载<
set<MM> mmData;
mmData.insert(MM("name1", 12));
mmData.insert(MM("name2", 12));
mmData.insert(MM("name2", 18));
//除数组外需要一般需要有begin() end()方法才可采用这种方式
for (auto v : mmData)
{
v.print();
}
}
二、bitset 包含头文件bitset
处理二进制的容器
int main()
{
//bitset<int> 错误 参数传长度,不需要传类型
//数字代表二进制的位数
//用string构造没问题
bitset<8> Data("11110000");
cout << Data << endl;
return 0;
}
三、map与multimap
存储的是数对类型
map
1、自带排序 默认从小到大
2、数据唯一性
测试pair类型
//模仿pair类型
template<class _Ty1,class _Ty2>
struct MyPair
{
_Ty1 first;
_Ty2 second;
MyPair(_Ty1 first, _Ty2 second) :first(first), second(second) {}
};
void testPair()
{
pair<int, string> pData(1, "string");
MyPair<int, string> myPData(1, "str");
cout << pData.first << " " << pData.second << endl;
}
(1)map
void testMap()
{
map<int, string> mapData;
//和上面相同
map<int, string, less<int>> mapData2;
//从大到小
map<int, string, greater<int>> mapData3;
//三种方式插入
//1、insert插入
mapData.insert(pair<int, string>(1, "str"));
//2、make_pair构件数对插入
mapData.insert(make_pair<int, string>(3, "str2"));
//3、单映射,直接采用数组下标的方式
//数组在一定程度上可以认为是映射
//-1对应string-1 map[first]=second
//first:键 second:值
//相同的键采用覆盖的方式
//相比于数组 下标没有任何要求 只要是整型数据即可
mapData[-1] = string("string - 1");
mapData[1] = "str-2";
//遍历
for (auto iter = mapData.begin();iter != mapData.end();iter++)
{
//*iter 代表pair类型
cout << iter->first << " " << iter->second << endl;
}
cout << mapData[1] << endl;;//访问值
//删除 通过键去删除
mapData.erase(1);
for (auto v : mapData)
{
cout << v.first << " " << v.second << endl;
}
}
(2)自定义类型
class MM
{
public:
MM() = default;
MM(string name, int age) :name(name), age(age) {}
void print()const
{
cout << name << " " << age << endl;
}
bool operator<(const MM& object)const
{
return this->name < object.name;
}
protected:
string name;
int age;
};
class Boy
{
public:
Boy() = default;
Boy(string name, int age) :name(name), age(age) {}
void print()const
{
cout << name << " " << age << endl;
}
protected:
string name;
int age;
};
void testUserData()
{
//需要重载 默认是采用MM排序 而MM内部有两个数据
map<MM, Boy> mBData;
mBData[MM("as", 12)] = Boy("qw", 14);
mBData[MM("asd", 22)] = Boy("qwe", 24);
for (auto v : mBData)
{//清楚v.first是MM类型 v.second是Boy类型
v.first.print();
v.second.print();
}
}
(3)多重数对
void testmultimap()
{
//因为存在相同的键,所以不能采用下标法插入
//其余和单映射相同
multimap<int, string> mulData;
mulData.insert(pair<int, string>(1, "str1"));
mulData.insert(pair<int, string>(1, "str2"));
mulData.insert(pair<int, string>(1, "str3"));
for (auto v : mulData)
{
cout << v.first << " " << v.second << endl;
}
}
四、initializer_list 包含头文件initializer_list
可以用来调整输入元素的个数
class MM
{
public:
MM(string a,string b,string c):a(a),b(b),c(c){}
MM(const initializer_list<string>& list)
{
for (auto iter = list.begin();iter != list.end();iter++)
{
cout << *iter << endl;
}
}
protected:
string a;
string b;
string c;
};
void print(initializer_list<int> list)
{
for (auto iter = list.begin();iter != list.end();iter++)
{
cout << *iter ;
}
cout << endl;
}
int main()
{
MM m1 = { "12","as" };
MM m2 = { "asd" };
print({ 1,2,3 });
print({ 1,2,3,4,5,6 });
print({ 1,2 });
return 0;
}
五、tuple 包含头文件tuple
(1)构造
void testTuple()
{//把任何类型的一组数据当做一组处理
tuple<string, int, int, string> mmInfo = { "MM",13,12,"qw" };
tuple<double, double, double> mmScore = make_tuple(12, 23, 12);
tuple<string, string> value = forward_as_tuple("as", "qw");
tuple<string, int, int, string> array1[3];
}
(2)访问
void visitTuple()
{
tuple<string, int, int, string> mmInfo = { "MM",13,12,"qw" };
//get方法 不能用for循环
cout << get<0>(mmInfo) << "\t";
cout << get<1>(mmInfo) << "\t";
cout << get<2>(mmInfo) << "\t";
cout << get<3>(mmInfo) << endl;
//tie方式访问
string name;
int age;
int num;
string tel;
tie(name, age, num, tel) = mmInfo;
cout << name << "\t" << age << "\t" << num << "\t" << tel << endl;
}
(3)连接
void Exoperator()
{
tuple<string, int, int, string> mmInfo = { "MM",13,12,"qw" };
tuple<double, double, double> mmScore = make_tuple(12, 23, 12);
auto result = tuple_cat(mmInfo, mmScore);
}
六、折叠参数 用 ... 表示
...Args 参数包 可适用任何类型的函数
1如何通过参数包定义一个变量: Args ...args
2如何使用参数包:args...
参数包的展开
1、递归的方式展开,自动做一个参数包的剥离过程
//需要递归终止函数 接收参数包内只有一个数的情况
template<class _Ty>
void print(_Ty data)
{
cout << data << " ";
}
template<class _Ty,class ...Args>
void print(_Ty data,Args ...args)
{
//例如参数包内为{"str",1,2} 先把str剥离给data
//剩下{1,2}再继续剥离
cout << data << " ";
print(args...);
}
2、采用列表的方式进行剥离函数
//2、列表的方式
template<class _Ty>
void printData(_Ty data)
{
cout << data << " ";
}
template<class ...Args>
void printArgs(Args ...args)
{
//(printData(args), 0) 剥离
initializer_list<int>{(printData(args), 0)...};
//int array[]={(printData(args), 0)...};相同
}
参数调用无限制
print(1, 2, 3, 4, "asd");
printArgs(1, 2, 3, 4, "asd");