- ubuntu12.04环境下使用kvm ioctl接口实现最简单的虚拟机
- Ubuntu 通过无线网络安装Ubuntu Server启动系统后连接无线网络的方法
- 在Ubuntu上搭建网桥的方法
- ubuntu 虚拟机上网方式及相关配置详解
CFSDN坚持开源创造价值,我们致力于搭建一个资源共享平台,让每一个IT人在这里找到属于你的精彩世界.
这篇CFSDN的博客文章关于C++11的统一初始化语法示例详解由作者收集整理,如果你对这篇文章有兴趣,记得点赞哟.
前言 。
本文主要给大家介绍了C++11统一初始化语法的相关内容,关于在当前新标准C++11的语法看来,变量合法的初始化器有如下形式:
1
2
3
4
|
X a1 {v};
X a2 = {v};
X a3 = v;
X a4(v);
|
其实,上面第一种和第二种初始化方式在本质上没有任何差别,添加=则是一种习惯上的行为。使用花括号进行的列表初始化语法,其实早在C++98时代就有了,只不过历史上他们只是被用来对数组元素进行初始化操作,以及初始化自定义POD类型的数据(简单理解就是可以memcpy复制对象的类型)。比如:
1
2
3
|
int
v1[] = {1, 2, 3, 4};
int
v2[5] = {1,2,3};
char
msg =
"hello, world!"
;
|
在使用列表来初始化数组的时候,如果声明数组的时候没有指定数组尺寸大小,则编译器就使用其列表包含的元素个数自动计算数组的尺寸;如果提供了数组尺寸,但是列表的元素数目小于数组尺寸,则系统会将剩余的元素全部赋值为0。如果是字符数组的话,C++还支持使用字符串常亮来进行初始化.
1、C++11的统一初始化器 。
在新标准C++11中这个东西使用范围和特性被大大的扩展了,而且已经成为了一个基础而又重要的利器,几乎可以执行任何的初始化操作,所以也被称为”Uniform initialization”,尽管国内还是习惯上称为列表初始化。因为他可以避免传统初始化中的诸多问题和缺陷,所以从Bjarne Stroustrup爷爷的《C++ 程序设计语言》描述口吻看来,列表初始化是被大力推荐使用的,即便用惯旧式初始化的C++程序员初看起来会很不习惯,但C++强烈建议使用上述第一种方式进行统一初始化操作.
C++11还引入了atomic原子类型,这种类型的变量(比如std::atomic)是无法使用传统=方式进行初始化的,只能使用{}或者()方式进行初始化;对于自定义类,如果其非静态成员变量具有默认值,则这个默认值只能用{}或者=进行初始化。总之也只有{}相比于其他类型可以用于任何位置,所以称为统一初始化器也不足为怪了.
防止类型收窄这是列表初始化的一个非常重要的特性,因为C++有很多隐式转换操作的发生,比如:浮点类型隐式转换为整形、长整型转换为短整型导致数据丢失,高精度的数据转换为低精度的数据,但凡是数据转换一次后再向回转换而不能得到原有表示的情况下,都可以称之为类型收窄。类型收窄常常会导致数据精度丢失,甚至潜在有意或无意错误的发生,尤其是那些不喜欢看编译警告的程序员常常会被忽略掉这些提示,而通过列表初始化的语法,编译器在编译期间进行这方面的强制检查,如果发生类型收窄则强制编译失败,从而能够杜绝相关问题的发生.
除了上面的优势之外,列表初始化语法还可以杜绝C++重构造语法的阴暗面。C++秉承的一个观念就是任何可以被解释为声明语法的语句都会被解释为声明语句,这会导致调用默认构造函数创建对象的时候被用错.
1
2
|
Widget w();
// 被解释为函数声明
Widget w{};
// OK
|
另外一种情况就是在容器使用的时候,也比较容易产生混淆的语义,这个时候使用列表初始初始化语法可以表明我们提供的列表是实际的元素。因为容器类的构造函数具有使用std::initializer_list作为重载的版本,所以如果要显式调用其某个版本的构造函数,就需要使用()来规避std::initializer_list的版本,称之为ctor-resort.
1
2
3
|
vector<
int
> v1{99};
// 一个元素,值为99
vector<
int
> v2(99);
// 实际是调用构造函数,共99个元素,默认值都是0
vector<string> v2(
"hello"
);
// Error,无匹配的构造函数
|
2、统一初始化器的阴暗面 。
使用列表初始化语法在绝大多数情况都能胜任,而且工作的很好,但是一旦同std::initializer_list结合起来,它的使用就会让人感觉混淆不清。在auto进行类型自动推导的时候,{}会默认被推导为std::initializer_list,如果这种结果不是你想要的,就需要进行规避以使用其他方式进行初始化操作.
1
2
|
auto z1 {99};
// initializer_list<int>
auto z2 = 99;
// int
|
如果你认为避免上面那个坑就结束了,呵呵……统一初始化器最大的麻烦还在于其和构造函数的结合。如果某个类的构造函数,其提供了一个接收std::initializer_list作为参数类型的重载版本,那么使用统一初始化句法进行构造对象的时候,编译器将会强烈优先使用具有初始化列表的重载版本.
我们知道,以std::initializer_list作为形参的话,其实参列表中的元素不要求和T完全匹配,而只需要能转换成T即可,此时只要转换后满足要求,编译器都会优先使用std::initializer_list作为形参的重载版本,即使其他重载的构造函数具有更优的匹配。在转换的过程中,如果类型提升满足要求则会正常调用;如果发生了窄化转换,则调用会失败报错;只有诸如字符串和数字这类无法转换的类型相互重载时候,重载机制才可能正常工作.
1
2
3
4
5
6
7
|
struct
Widget {
Widget(
int
i,
bool
b) { cout <<
"1"
<< endl; }
Widget(
int
i,
double
d) { cout <<
"2"
<< endl; }
Widget(std::initializer_list<
bool
> il) { cout <<
"3"
<< endl; }
};
Widget w1{1,
true
};
// 3
Widget w2{9,
true
};
// Error
|
还有一个极端情况,如果一个自定义类既有默认构造函数,也有std::initializer_list作为参数的构造函数,则使用{}作为初始化值构造对象的话,C++标准显式规定了调用其默认构造函数,如果想要以空列表的语义调用第二个版本,则可以使用({})的方式进行初始化.
3、C++对象的默认初始化行为 。
列表初始化还允许使用空列表{}作为初始化器,这时候元素都使用默认值进行初始化,或者调用自定义类型的默认构造函数,所以列表初始化的变量其默认行为都是良好的.
对于我们自定义的数据类型,如有必要也可以,在具体调用的时候不需要具体元素类型为T,只要能转化成T即可,在构造函数中使用迭代器访问列表中的每个元素.
C++规定,如果定义的变量没有指定初始化器,则全局变量、名字空间变量、局部static变量、static成员将会执行相应数据类型的空列表{}初始化;而对于局部变量、自由存储区上的变量(堆对象),除非它们定义于用户自定义类型的默认构造函数中,否则不会执行默认初始化,这种情况是需要格外需要注意的,操作未初始化变量可能会造成不确定的行为.
1
2
|
int
* p{
new
int
{} };
char
* q{
new
char
[2014]{} }
|
呵呵,如果突然看着一大坨C++代码使用{}进行初始化,可能会一时间觉得奇怪,不过习惯也就好啦! 。
总结 。
以上就是这篇文章的全部内容了,本文还有许多不足,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,如果有疑问大家可以留言交流,谢谢大家对我的支持.
参考 。
原文链接:https://taozj.net/201710/list-initialize.html 。
最后此篇关于关于C++11的统一初始化语法示例详解的文章就讲到这里了,如果你想了解更多关于关于C++11的统一初始化语法示例详解的内容请搜索CFSDN的文章或继续浏览相关文章,希望大家以后支持我的博客! 。
大家好,我是汤师爷~ 什么是订单履约系统? 订单履约是从消费者下单支付到收到商品的全流程管理过程,包括订单接收、订单派单、库存分配、仓储管理和物流配送等环节,核心目标是确保商品准时、准确地送达消费
大家好,我是汤师爷~ 今天聊聊促销系统整体规划。 各类促销活动的系统流程,可以抽象为3大阶段: B端促销活动管理:商家运营人员在后台系统中配置和管理促销活动,包括设定活动基本信息、使用规则
全称“Java Virtual Machine statistics monitoring tool”(statistics 统计;monitoring 监控;tool 工具) 用于监控虚拟机的各种运
主要是讲下Mongodb的索引的查看、创建、删除、类型说明,还有就是Explain执行计划的解释说明。 可以转载,但请注明出处。  
1>单线程或者单进程 相当于短链接,当accept之后,就开始数据的接收和数据的发送,不接受新的连接,即一个server,一个client 不存在并发。 2>循环服务器和并发服务器
详解 linux中的关机和重启命令 一 shutdown命令 shutdown [选项] 时间 选项: ?
首先,将json串转为一个JObject对象: ? 1
matplotlib官网 matplotlib库默认英文字体 添加黑体(‘SimHei')为绘图字体 代码: plt.rcParams['font.sans-serif']=['SimHei'
在并发编程中,synchronized关键字是常出现的角色。之前我们都称呼synchronized关键字为重量锁,但是在jdk1.6中对synchronized进行了优化,引入了偏向锁、轻量锁。本篇
一般我们的项目中会使用1到2个数据库连接配置,同程艺龙的数据库连接配置被收拢到统一的配置中心,由DBA统一配置和维护,业务方通过某个字符串配置拿到的是Connection对象。  
实例如下: ? 1
1. MemoryCahe NetCore中的缓存和System.Runtime.Caching很相似,但是在功能上做了增强,缓存的key支持object类型;提供了泛型支持;可以读缓存和单个缓存
argument是javascript中函数的一个特殊参数,例如下文,利用argument访问函数参数,判断函数是否执行 复制代码 代码如下: <script
一不小心装了一个Redis服务,开了一个全网的默认端口,一开始以为这台服务器没有公网ip,结果发现之后悔之莫及啊 某天发现cpu load高的出奇,发现一个minerd进程 占了大量cpu,googl
今天写这个是为了 提醒自己 编程过程 不仅要有逻辑 思想 还有要规范 代码 这样可读性 1、PHP 编程规范与编码习惯最主要的有以下几点: 1 文件说明 2 funct
摘要:虚拟机安装时一般都采用最小化安装,默认没有lspci工具。一台测试虚拟网卡性能的虚拟机,需要lspci工具来查看网卡的类型。本文描述了在一个虚拟机中安装lspci工具的具体步骤。 由于要测试
1、修改用户进程可打开文件数限制 在Linux平台上,无论编写客户端程序还是服务端程序,在进行高并发TCP连接处理时,最高的并发数量都要受到系统对用户单一进程同时可打开文件数量的限制(这是因为系统
目录 算术运算符 基本四则运算符 增量赋值运算符 自增/自减运算符 关系运算符 逻
如下所示: ? 1
MapperScannerConfigurer之sqlSessionFactory注入方式讲解 首先,Mybatis中的有一段配置非常方便,省去我们去写DaoImpl(Dao层实现类)的时间,这个
我是一名优秀的程序员,十分优秀!