1.initializer_list
如果一个函数的实参数量不可预知,但所有实参的类型相同,那么我们就可以使用 initializer_list 来接收。
initializer_list 是一个类模板,其类型模板参数就是待保存的数据的类型。需要注意的是,initializer_list 对象中的元素永远是常量值,不能被改变。
拷贝或赋值一个 initializer_list 对象,不会拷贝列表中的元素,原对象和拷贝或赋值出来的对象共享列表中的元素。
#include <iostream>
using namespace std;
void fun(initializer_list<string> array)
{
for (auto& it : array)
{
cout << it << endl;
}
cout << array.size() << endl;
}
int main()
{
fun({ "abc", "def", "gh", "ijk" });
return 0;
}
2.省略号形参…
带 ...
的可变参函数的所有参数是存储在线性连续的栈空间中的。
带 ...
的可变参函数必须至少有一个普通参数,形参不能完全是 ...
,这样就可以通过这个普通参数来寻址后续的所有可变参数的类型及值。
如果有多个普通参数,那么 va_start
必须和 ...
的前一个普通参数绑定在一起。
...
只能出现在形参列表的最后一个位置。
...
之前的逗号可以省略。
可变参数的类型一般是数值型或字符串型,其他类类型一般不能正常处理。
2.1 整型类型
#include <iostream>
#include <stdarg.h>
using namespace std;
double fun(int num, ...) // num是可变参数的数量
{
va_list valist; // 创建一个va_list类型的变量
double sum = 0;
va_start(valist, num); // 使valist指向...的前一个参数
for (int i = 0; i < num; ++i)
{
sum += va_arg(valist, int); // va_arg的第二个参数表示返回类型为int
}
va_end(valist); // 释放valist
return sum;
}
int main()
{
cout << fun(3, 10, 20, 30) << endl; // 60
return 0;
}
2.2 字符串类型
#include <iostream>
#include <stdarg.h>
using namespace std;
void print(const char* msg, ...) // msg是可变参数的数量
{
va_list valist; // 创建一个va_list类型的变量
int num = atoi(msg);
va_start(valist, msg); // 使valist指向...的前一个参数
int count = 0;
while (count < num)
{
char* p = va_arg(valist, char*); // va_arg的第二个参数表示返回类型为char*
printf("第%d个参数是: %s\n", count, p);
count++;
}
va_end(valist); // 释放valist
}
int main()
{
print("2", "Hello", "World");
return 0;
}