C++2.0新特性(二)——<一致性初始化、Initializer_list 、for循环、explicit>
一、一致性初始化(uniform initialization)
之前初始化时存在多个版本,让使用者使用时比较混乱,现在提供一种万用的初始化方法,就是使用大括号。
原理解析:当编译器看到大括号包起来的东西时,会生成一个initializer_list<T>(initializer_list它其实是关联一个array<T,n>),然后再调用构造函数时,一个个从array分解取出来然后调用构造函数,但是如果这个函数自身提供了initializer_list<T>参数类型的构造函数时,则不会分解而是直接传过去。

// 初值列:强迫初始化为 0 (或nullptr).
int i; // i 初始化为未定义值.
int j{}; // j 初始化为 0 (大括号可以用来设初值)
int * p; // p 初始化为未定义值.
int * q{}; // q 初始化为 0 (大括号可以用来设初值)
// 窄化(精度降低或造成数值变动)对大括号而言是不成立的.
int x0(3.4); // ok.
int x1 = 3.4; // ok.
int x2 { 3.4 }; // wrong.(不允许窄化数据处理,其实我的编译器只给警告)
int x3 = { 3.4 }; // wrong.(不允许窄化数据处理,其实我的编译器只给警告)
std::vector<int> v1 { 1, 2, 3 }; // ok.
std::vector<int> v2 { 1.1, 2.2, 3.3 }; // wrong.(不允许窄化数据处理,其实我的编译器只给警告)
二、Initializer_list

注意:只要编译器遇到大括号里面有一些数,再传值的时候都会去生成一个initializer_list<T>去处理,这个和前面一章节提到的不定参数模板相比,这个必须类型要一致,而后者则可以类型随意组合
三、for循环
1、2.0新增新语法本质是将后边的集合取出来依次赋值给前面申明的变量


注意:
- 上图中申明引用类型的速度快很多,因为引用相当于指针的操作只操作4个字节,而非引用的速度开销随着数据类型所占空间增长而增大,且声明引用后的修改将直接影响到集合中数据的值;
- 用for操作容器时,标准库规定,关联容器都不允许通过迭代器修改修改容器的值,也就是说上面申明为引用的for循环无法修改关联容器里的数值(因为关联容器的迭代器是const);
- 当解引用一个关联容器迭代器时,会获得一个类型为value_type的值的引用。对于map而言,value_type是一个pair,pair由first和second组成,first成员保存const关键字,second保存值,而对于set而言,set的迭代器也是const,虽然set定义了iterator和const_iterator类型,但是两种类型都只允许只读set的元素;
- 因为set使用红黑树做底部结构,但是set只有一个元素(key和data是一样得,也就是说key就是value),所以set是不允许改变元素值得,所以在实现上,set的迭代器拿到的是const的iterator,是不能修改的;
- 我们通常不去对关联容器使用泛型算法,因为set的关键字是const的,而map的元素pair的第一个成员也是const的,因此不能将关联容器传递给修改或重排元素的算法(实际中我们使用泛型算法一般只把关联容器当成我们要操作数据的源头位置或者目的位置,例如copy算法将元素从一个关联容器拷贝到另一个序列)。
2、但对于explicit类型申明的转换是不可以的

四、explicit
explicit关键字一直存在,只能作用在构造函数中, 目的是阻止编译器进行不应该允许的构造函数进行隐式转换(也就是说不让编译器自作聪明),声明为explicit的构造函数不能进行隐式转换,只能允许使用者明确调用构造函数;
在C++2.0中,explicit可以支持不止一个参数的构造函数使用(之前只能支持传入一个实参)
1、2.0以前,explicit只能作用在一个实参的构造函数上
#include <iostream>
class Single{ public:
//普通构造函数(单一实参)
Single(int a,int b = 0):num(a)
{}
private:
int num;
}; class SingleMore {
public:
//explicit 显示申明构造函数(单一实参)
explicit SingleMore(int a) :num(a)
{}
private:
int num;
}; #if 1
int main(int argc, char* argv[])
{
Single single();
Single single2 = ; SingleMore singleMore();
SingleMore singleMore2 = ;//编译报错,E0415 不存在从 "int" 转换到 "SingleMore" 的适当构造函数 return ;
}
#endif
2、2.0以后explicit可以适用多个实参的构造函数
struct A
{
A(int) { } // 转换构造函数
A(int, int) { } // 转换构造函数 (C++11)
operator bool() const { return true; }
}; struct B
{
explicit B(int) { }
explicit B(int, int) { }
explicit operator bool() const { return true; }
}; int main()
{
A a1 = ; // OK :复制初始化选择 A::A(int)
A a2(); // OK :直接初始化选择 A::A(int)
A a3 {, }; // OK :直接列表初始化选择 A::A(int, int)
A a4 = {, }; // OK :复制列表初始化选择 A::A(int, int)
A a5 = (A); // OK :显式转型进行 static_cast
if (a1) ; // OK :A::operator bool()
bool na1 = a1; // OK :复制初始化选择 A::operator bool()
bool na2 = static_cast<bool>(a1); // OK :static_cast 进行直接初始化 // B b1 = 1; // 错误:复制初始化不考虑 B::B(int)
B b2(); // OK :直接初始化选择 B::B(int)
B b3 {, }; // OK :直接列表初始化选择 B::B(int, int)
// B b4 = {4, 5}; // 错误:复制列表初始化不考虑 B::B(int,int)
B b5 = (B); // OK :显式转型进行 static_cast
if (b2) ; // OK :B::operator bool()
// bool nb1 = b2; // 错误:复制初始化不考虑 B::operator bool()
bool nb2 = static_cast<bool>(b2); // OK :static_cast 进行直接初始化
}

C++2.0新特性(二)——<一致性初始化、Initializer_list 、for循环、explicit>的更多相关文章
- C# 6.0 新特性 (二)
自动属性初始化表达式 有过正确实现结构经验的所有 .NET 开发人员无疑都为一个问题所困扰:需要使用多少语法才能使类型固定不变(为 .NET 标准建议的类型).此问题实际上是只读属性存在的问题: 定义 ...
- c# 6.0新特性(二)
写在前面 上篇文章介绍了c#6.0的using static,Auto Property Initializers,Index Initializers新的特性,这篇文章将把剩下的几个学习一下. 原文 ...
- C#发展历程以及C#6.0新特性
一.C#发展历程 下图是自己整理列出了C#每次重要更新的时间及增加的新特性,对于了解C#这些年的发展历程,对C#的认识更加全面,是有帮助的. 二.C#6.0新特性 1.字符串插值 (String In ...
- [C#]6.0新特性浅谈
原文:[C#]6.0新特性浅谈 C#6.0出来也有很长一段时间了,虽然新的特性和语法趋于稳定,但是对于大多数程序猿来说,想在工作中用上C#6.0估计还得等上不短的一段时间.所以现在再来聊一聊新版本带来 ...
- C#6.0,C#7.0新特性
C#6.0新特性 Auto-Property enhancements(自动属性增强) Read-only auto-properties (真正的只读属性) Auto-Property Initia ...
- 从C# 2.0新特性到C# 3.5新特性
一.C# 2.0 新特性: 1.泛型 List<MyObject> obj_list=new List(); obj_list.Add(new MyObject()); 2.部分类(par ...
- [翻译] C# 8.0 新特性 Redis基本使用及百亿数据量中的使用技巧分享(附视频地址及观看指南) 【由浅至深】redis 实现发布订阅的几种方式 .NET Core开发者的福音之玩转Redis的又一傻瓜式神器推荐
[翻译] C# 8.0 新特性 2018-11-13 17:04 by Rwing, 1179 阅读, 24 评论, 收藏, 编辑 原文: Building C# 8.0[译注:原文主标题如此,但内容 ...
- android6.0、7.0、8.0新特性总结之开发应用时加以考虑的一些主要变更。
android6.0 参考一:简书Android 6.0 新特性详解 参考二:关于Android6.0以上系统的权限问题 参考三:值得你关注的Android6.0上的重要变化(一) 参考四:值得你关注 ...
- python-3.8.0 新特性之赋值表达式
[python-3.8.0 新特性之赋值表达式] 赋值表达式的语法是这样的“ name := expression ”,形式上看和赋值语句 “ = ” 差不多,就作用上来看也雷同.也就是说 “:=” ...
随机推荐
- NEST search查询
/// <summary> /// GET /megacorp/employee/_search /// </summary> /// <returns></ ...
- React Native 开发豆瓣评分(八)首页开发
首页完成效果展示: 一.开发占位图组件 在没有数据的时候使用占位图替代 items 的位置. 在 components 目录里创建 moviesItemPlaceholder.js import Re ...
- React Native 开发豆瓣评分(六)添加字体图标
添加依赖 yarn add react-native-vector-icons Link 依赖 react-native link react-native-vector-icons 使用默认字体图标 ...
- c++ 使用torchscript 加载训练好的pytorch模型
1.首先官网上下载libtorch,放到当前项目下 2.将pytorch训练好的模型使用torch.jit.trace导出为.pt格式 import torch from skimage import ...
- [daily][archlinux] pacman 安装软件时404的问题
时常,我们在archlinux上pacman安装一个软件时,会遇见如图这样的问题: “The requested URL returned error: 404” [classic_tong @ 2 ...
- IAR常用快捷键和使用小技巧
1.复制和粘贴几行的部分代码 需求:有时候我们需要复制几行代码的后半部分,不需要复制前半部分.方法:按住Alt键,再用鼠标拖动就可以复制和粘贴后半部分 2.复制一行 复制一行的时候,我们一般是从最后开 ...
- 运维开发笔记整理-Django模型语法
运维开发笔记整理-Django模型语法 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.模型基本概念 1>.什么是模型 模型是你的数据唯一的,权威的信息源.它包含你所存储数 ...
- VMware安装ubantu
下载ubantu镜像文件: http://mirror.pnl.gov/releases/xenial/ http://mirrors.melbourne.co.uk/ubuntu-releases/ ...
- linux一些配置
ifconfig 查询.设置网卡和ip参数 ifup ens33 启动网卡 ifdown 关闭网卡 systemctl restart/start/stop network 重启.开始.关闭 网络服务 ...
- 微信小程序~调试
小程序调试面板 模拟器 模拟器模拟微信小程序在客户端真实的逻辑表现,对于绝大部分的 API 均能够在模拟器上呈现出正确的状态. 自定义编译 点击工具栏中的编译按钮或者使用快捷键 Ctrl(⌘) + B ...
