实例代码
//
// 可变参数函数、initializer_list、省略号形参
#include <iostream>
#include <vector>
#include <map>
#include <functional>
#include <algorithm>
#include <ctime>
#include <initializer_list>
#include <stdarg.h>
using namespace std;
void printvalue(initializer_list<string> tmpstr) {
for (auto beg = tmpstr.begin(); beg != tmpstr.end(); ++beg) {
cout << (*beg).c_str() << endl;
}
// 范围for 方式 遍历
//for (auto &tmppitem : tmpstr) { // 用引用,节省性能
// cout << tmppitem.c_str() << endl;
//}
cout << tmpstr.size() << endl; // 打印列表中元素数量
}
class CT {
public:
CT(const initializer_list<int> &tmpvalue) {
// ...
int test = 1;
}
};
// 带 ... 的可变参数函数 函数中需要用到几个宏
double sum(int num, ...) { // num 里边传递进来的可变参数的数量
//类型定义(宏)
va_list valist; // 创建一个va_list 类型的变量
double sum = 0;
va_start(valist, num); // 使valist指向起始的参数
for (int i = 0; i < num; i++) {
//遍历参数
sum = sum + va_arg(valist, int); // 参数2说明返回的类型为int
}
va_end(valist); // 释放valist
return sum;
}
int main()
{
//一、可变参数函数
//这种能够接收非固定个数参数的函数就是可变参数函数;
//initializer_list标准库类型,用于处理可变参数问题,该类型能够使用的前提条件是,所有的实参类型相同
//二、initializer_list (初始化列表)
//如果一个函数,它的实参数量不可预知,但是所有参数的类型相同,我们就可以使用这个initializer_list类型的形参来接收
//initializer_list 是 C++ 11中提供的新类型,也是一个类模板
//我们把initializer_list理解成某种类型值得数组。这个类模板里指定的类型模板参数就是这个数组里保存的数据的类型。
initializer_list<int> myarray; // 看成数组,元素类型是int
initializer_list<int> myarray1 = { 10, 20, 30, 40, 50 };
// 注意initializer_list 队列中的元素永远是常量值,不能被改变。
//2.1 begin()、end()遍历、size()获取元素个数
printvalue({ "aa", "bb", "cc" }); // 若要往initializer_list形参传递一个序列,则必须要把这个序列放到{}里括起来作为一个整体。
//其实C++ 11 将使用大括号{}初始化{初始化列表}作为一种比较通用的初始化方式,可用于很多的类型。
//函数initializer_list形参的函数也可以包含其他形参,互不影响。
//2.2 拷贝和赋值
//拷贝、赋值一个initializer_list对象,不会拷贝列表中的元素,原来对象和拷贝或者赋值出来的对象共享表中的元素。
initializer_list<string> myarray3 = { "aa", "bb", "cc" };
initializer_list<string> myarray4(myarray3); // 定义时初始化
initializer_list<string> myarray5;
myarray5 = myarray4; //赋值
//观察上面 myarray3 myarray4 myarray5 列表中的元素,地址都是相同的,可见共享。
//2.3 初始化列表做构造函数参数
CT ct1 = { 10, 20, 30, 40 }; // 隐式类型转换
//三、省略号形参(...) 可变参数函数
// 这种省略形参式的可变参数函数,虽然参数数量不固定,但是函数的所有参数是存储在线性连续的栈空间中的。
// 而且带... 的可变参数函数必须至少要有一个普通参数,我们就可以通过这个普通参数来寻址后续的所有可变参数的类型以及值。
cout << sum(3, 100, 200, 300) << endl;
//printf 也是使用上面的方式实现变参
printf("val = %d, val2 = %d", 15, 17);
//注意:
//a). 至少有一个有效的形参,形参不能是完全为...
//b). ...形参只能出现在形参列表最后一个位置。 void myfunc(参数列表, ...);
//c). 如果有多个普通参数,那么va_start(valist, num); 第二个参数必须绑...之前的那个参数。
//d). 一般这些可变参数类型是数值型或者字符串型还能正常处理,其他类型一般都不能正常处理,所以...用的场合并不多。
//f). 不建议在C++中使用...
system("pause");
}