116 C++ 可变参数函数,initializer_list (初始化列表), 省略号形参

本文主要是介绍116 C++ 可变参数函数,initializer_list (初始化列表), 省略号形参,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

一 可变参数函数

有时候我们传递的参数是不固定的。

这种能接受非固定个数参数的函数就是可变参数函数

怎么实现呢?就要用到 initializer_list 标准库类型

该类型能够使用的前提条件是:所有的实参类型相同。

二,initializer_list(初始化列表) C++11的类模版

如果一个函数,它的实参数量不可预知,但是所有参数的类型相同,我们就可以使用这个initializer_list 类型的形参来接收

我们把 initializer_list 理解成某种类型值的数组。

这个类模版里面指定的类型模版参数就是数组里保存的数据的类型

需要包含 #include <initializer_list> 头文件 或者 iostream

要注意的是 initializer_list<int >myarray 中的元素永远都是常量值。不能被改变。

1. 基本方法 :begin(), end()遍历,size()获取元素个数

void func150(initializer_list<int> myarray) {//遍历形参,类似于迭代器的遍历for (auto iter = myarray.begin(); iter != myarray.end();++iter) {cout << "  " << * iter ;}cout << endl;cout << "myarray.size = " << myarray.size() << endl;
}
void func151(initializer_list<string> myarraystr) {//遍历形参,类似于迭代器的遍历for (auto iter = myarraystr.begin(); iter != myarraystr.end(); ++iter) {cout << "  " << (*iter).c_str();}cout << endl;cout << "myarraystr.size = " << myarraystr.size() << endl;
}void main() {initializer_list<int> myarray;//就看成一个数组了,元素类型是int。initializer_list<int> myarray2 = { 12,16,18,80,90 };//一共5个元素//要注意的是 myarray 或者myarray2中的元素永远都是常量值。func150(myarray2);func151({"nihao","china"});cout << "duandian" << endl;//12  16  18  80  90//	myarray.size = 5//	nihao  china//	myarraystr.size = 2//	duandian
}

上述代码中值的说一下的地方:

C++11使用大括号里面放值,做为一种比较通用的初始化方式,可用于很多的类型。

begin() 和 end()方法类似于 迭代器的

2. initializer_list 拷贝和赋值 不会额外生成一份,是共享的

initializer_list 是个类模版,具体case就是一个类对象,那么这个类对象肯定也是可以拷贝和赋值的

copy 和 赋值 都不会 重新copy一份,而是原来的 mystr 和 mystr1共享一份,mystr 和 mystr2共享一份

	// copy 和 赋值 都不会 重新copy一份,而是原来的 mystr 和 mystr1共享一份,mystr 和 mystr2共享一份initializer_list<string> mystr = {"nihao","china","zhenxing"};initializer_list<string> mystr1(mystr);initializer_list<string> mystr2;mystr2 = mystr;//debug发现  mystr mystr1 mystr2 中里面的string内容的地址都是一致的//	mystr[原始视图] = { _First = 0x008ffdac "nihao" _Last = 0x008ffe00 < 字符串中的字符无效。 > }//	mystr1[原始视图] = { _First = 0x008ffdac "nihao" _Last = 0x008ffe00 < 字符串中的字符无效。 > }//	mystr2[原始视图] = { _First = 0x008ffdac "nihao" _Last = 0x008ffe00 < 字符串中的字符无效。 > }cout << "duandian" << endl;

3.initializer_list 初始化列表做构造函数参数

class Teacher158 {
public:explicit Teacher158(const initializer_list<int> &temvalue) {cout << "duandian1" << endl;}Teacher158(string str) {}};void main() {cout << "111" << endl;Teacher158 tea(); //是一个函数声明,它声明了一个名为 tea 的函数,返回类型为 Teacher158cout << "222" << endl;Teacher158 tea1({1,2,3});Teacher158 tea3{ 100000,2000000,3000000 };//Teacher158 tea2 = { 4,5,66666666 };//隐式类型转换,还是会调用构造函数。//如果我们想禁止 隐式类型转换,需要在构造方法前面加上 explicit
}

三 省略号形参(...)  省略号形参一般无法正确处理类类型对象,在C++要少用,最好不要用,这里写出来是为了知识点的完整。

 省略号形参(...) 也是可以变参数函数。能正确的处理int ,char *;

虽然这种参数数量不固定,但是函数的所有参数是存储在线性的连续的栈空间的。

而且这种可变参数函数必须至少有一个普通参数,我们就可以通过这个普通参数来寻址后续的所有可变参数的类型以及值。

需要包含头文件 #include <stdarg.h>

#include <stdarg.h>//需要用到 stdarg.h中的几个宏
double func159(int num, ...) {//一般num里面传递进来的是可变参数的数量。va_list valist;//创建一个 va_list类型的变量,按f12 看va_list 实际上是 char*//该函数的目的是计算传递进来的 可变参数的和double sum = 0;va_start(valist, num);//使valist指向起始的参数for (int i = 0; i < num; ++i) {sum = sum + va_arg(valist, int);//va_arg是个宏,va_arg宏的第二个参数表明 func159函数除第一个参数外,都是int//该宏用于变参数函数调用过程中,type是当前参数类型,调用该宏后,ap指向变参数列表中的下一个参数,返回ap指向的参数值,是一个类型为type的表达式。}va_end(valist);//释放valistreturn sum;
}void main() {cout << func159(5, 100, 200, 300, 400, 500) << endl;
}

注意说明:

1. 至少有一个有效的形参,形参不能全部是...

2.三个.只能出现在形参列表的最后一个位置

3,三个.之前的,是可以省略的

4,如果有多个普通参数,那么va_start(valist, num)中的num,必须是...紧前面的那个

5,一般只能处理 数值型 或者char * 型,遇到类类型不能正常处理

6.在C++中不建议使用,能看懂就行

这篇关于116 C++ 可变参数函数,initializer_list (初始化列表), 省略号形参的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/724088

相关文章

JVM 的类初始化机制

前言 当你在 Java 程序中new对象时,有没有考虑过 JVM 是如何把静态的字节码(byte code)转化为运行时对象的呢,这个问题看似简单,但清楚的同学相信也不会太多,这篇文章首先介绍 JVM 类初始化的机制,然后给出几个易出错的实例来分析,帮助大家更好理解这个知识点。 JVM 将字节码转化为运行时对象分为三个阶段,分别是:loading 、Linking、initialization

【C++ Primer Plus习题】13.4

大家好,这里是国中之林! ❥前些天发现了一个巨牛的人工智能学习网站,通俗易懂,风趣幽默,忍不住分享一下给大家。点击跳转到网站。有兴趣的可以点点进去看看← 问题: 解答: main.cpp #include <iostream>#include "port.h"int main() {Port p1;Port p2("Abc", "Bcc", 30);std::cout <<

C++包装器

包装器 在 C++ 中,“包装器”通常指的是一种设计模式或编程技巧,用于封装其他代码或对象,使其更易于使用、管理或扩展。包装器的概念在编程中非常普遍,可以用于函数、类、库等多个方面。下面是几个常见的 “包装器” 类型: 1. 函数包装器 函数包装器用于封装一个或多个函数,使其接口更统一或更便于调用。例如,std::function 是一个通用的函数包装器,它可以存储任意可调用对象(函数、函数

Andrej Karpathy最新采访:认知核心模型10亿参数就够了,AI会打破教育不公的僵局

夕小瑶科技说 原创  作者 | 海野 AI圈子的红人,AI大神Andrej Karpathy,曾是OpenAI联合创始人之一,特斯拉AI总监。上一次的动态是官宣创办一家名为 Eureka Labs 的人工智能+教育公司 ,宣布将长期致力于AI原生教育。 近日,Andrej Karpathy接受了No Priors(投资博客)的采访,与硅谷知名投资人 Sara Guo 和 Elad G

hdu1171(母函数或多重背包)

题意:把物品分成两份,使得价值最接近 可以用背包,或者是母函数来解,母函数(1 + x^v+x^2v+.....+x^num*v)(1 + x^v+x^2v+.....+x^num*v)(1 + x^v+x^2v+.....+x^num*v) 其中指数为价值,每一项的数目为(该物品数+1)个 代码如下: #include<iostream>#include<algorithm>

C++11第三弹:lambda表达式 | 新的类功能 | 模板的可变参数

🌈个人主页: 南桥几晴秋 🌈C++专栏: 南桥谈C++ 🌈C语言专栏: C语言学习系列 🌈Linux学习专栏: 南桥谈Linux 🌈数据结构学习专栏: 数据结构杂谈 🌈数据库学习专栏: 南桥谈MySQL 🌈Qt学习专栏: 南桥谈Qt 🌈菜鸡代码练习: 练习随想记录 🌈git学习: 南桥谈Git 🌈🌈🌈🌈🌈🌈🌈🌈🌈🌈🌈🌈🌈�

【C++】_list常用方法解析及模拟实现

相信自己的力量,只要对自己始终保持信心,尽自己最大努力去完成任何事,就算事情最终结果是失败了,努力了也不留遗憾。💓💓💓 目录   ✨说在前面 🍋知识点一:什么是list? •🌰1.list的定义 •🌰2.list的基本特性 •🌰3.常用接口介绍 🍋知识点二:list常用接口 •🌰1.默认成员函数 🔥构造函数(⭐) 🔥析构函数 •🌰2.list对象

如何在页面调用utility bar并传递参数至lwc组件

1.在app的utility item中添加lwc组件: 2.调用utility bar api的方式有两种: 方法一,通过lwc调用: import {LightningElement,api ,wire } from 'lwc';import { publish, MessageContext } from 'lightning/messageService';import Ca

06 C++Lambda表达式

lambda表达式的定义 没有显式模版形参的lambda表达式 [捕获] 前属性 (形参列表) 说明符 异常 后属性 尾随类型 约束 {函数体} 有显式模版形参的lambda表达式 [捕获] <模版形参> 模版约束 前属性 (形参列表) 说明符 异常 后属性 尾随类型 约束 {函数体} 含义 捕获:包含零个或者多个捕获符的逗号分隔列表 模板形参:用于泛型lambda提供个模板形参的名

4B参数秒杀GPT-3.5:MiniCPM 3.0惊艳登场!

​ 面壁智能 在 AI 的世界里,总有那么几个时刻让人惊叹不已。面壁智能推出的 MiniCPM 3.0,这个仅有4B参数的"小钢炮",正在以惊人的实力挑战着 GPT-3.5 这个曾经的AI巨人。 MiniCPM 3.0 MiniCPM 3.0 MiniCPM 3.0 目前的主要功能有: 长上下文功能:原生支持 32k 上下文长度,性能完美。我们引入了