IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> C++知识库 -> C++17 (1) -> 正文阅读

[C++知识库]C++17 (1)

if-init

C++17新增,变量可以在if条件表达式内初始化,

//before C++17
int p = do_something();
if(p){
	//...
}

//now
if(int p = do_something(); p){
	//...
}
  • 如果你的变量p仅仅在if范围内使用,那么就可以使用if-init。这样做的好处就是控制了p的生命周期和作用域,一旦离开if语句,p立刻销毁,提高了一点效率,而且你可以在下面的代码中再次定义变量p,不会引起冲突。
  • p的作用域是整个if语句,
if(p = do_something(); p) {
	//p可见
}
else if(q = do_other(); q){
	//p && q都可见
}
else{
	//p && q都可见
}

if-init可用的另外一个地方就是锁(lock),

  • 下面这个栗子来自我的另外一篇博客,单例模式
static Singleton* GetInstance(){ 
    if(_instance == nullptr){  
{  //这一对大括号只是限制锁的作用域
	unique_lock<mutex> lck(_mut);
	if(_instance == nullptr)
	_instance = new Singleton;
 } //限制大括号
}
 	return _instance;
}
  • 上面是单例模式获得对象的静态函数,其他部分我已省略。
  • 可以看到在注释行多出一对大括号,这是C++17之前的手法,利用作用域限制锁的生命周期。否则就会扩大锁的范围,浪费资源。
  • C++17之后我们可以利用if-init,这两个写法等价。
//C++17
static Singleton* GetInstance(){ 

    if(_instance == nullptr){ 
	if(unique_lock<mutex> lck(_mut); _instance == nullptr)   //if-init
	_instance = new Singleton;
 }
 
 	return _instance;
}
  • 可以看到代码简洁不少。if-int和下面要介绍的结构体绑定也有联动。
  • switch语句也有同样的switch-int方式。使用方法和if相同,不再演示。

Structured Bindings

  • C++17引入结构体绑定。你可能使用过C++11引入的tuple。
std::tuple<std::string, int> create_person(){
	return {"zzh", 20};
}

//如何获得tuple内的每个“对象”?
std::tuple<std::string, int> my = create_person();
std::string& name = std::get<0>(my);
int& age = std::get<1>(my);

//or
std::string name;
int age; 
std::tie(name, age) = my;
  • 但是,这两种方法都不太好。让我们看看结构体绑定的做法。
auto[name, age] = create_person(); //over !
  • 必须使用auto。
  • 不必像tie一样为每个对象单独声明。
  • 还可以使用const auto, auto&等等。
  • 结构体底层实际上就是通过get函数实现的。
auto __temp = create_person(); //auto[] ->这里是auto
auto& name = std::get<0>(__temp);
auto& age = std::get<1>(__temp);
  • 先拷贝一份__temp,然后去调用get函数。其中name和age是引用。
  • 因为结构体绑定中我们使用auto,所以推导__temp也使用auto。
struct X {
	int a_ = 0;
};

int main() {
	auto [value1] = X(); //OK
	// auto __temp = X();
	//auto& value1 = __temp.a_;
	
	auto& [value2] = X(); //WRONG!
	// auto& __temp = X(); X()拷贝临时对象,不能将非const引用绑定到常量上!!
	
	const auto [value3] = X(); //OK
	//const auto __temp = X();
	//auto& value3 = __temp.a_;
	return 0;
}
  • 从上面我们可以看到,我们自己写的类也可以用于结构体绑定。这应该是正常的,因为tuple没有什么特殊的地方,毕竟tuple也不是语言特性。
  • 结构体绑定使用的条件是什么呢?
  • 这里简单介绍几点:
  1. 类所有成员变量为public;
  2. 如果类成员变量为private。那么你需要为该类提供get成员函数或者一个全局范围内的get函数,且你需要在std(没错,在std中)为你的类型提供特化版本的tuple_size, tuple_element。
  • 标准库中满足这几点条件的大致有3个:

std::tuple, std::array, std::pair。

	int arr[4] = { 1, 2, 3, 4 }; //普通数组
	auto [a, b, c, d] = arr;
	
	std::array<int, 3> arrayObj{ 1, 2, 3 }; //array
	auto [e, f, g] = arrayObj;

	std::pair<int, std::string> node(1, "zzh"); //pair
	auto [age, name] = node;
  • 或者利用for循环+结构体绑定:
for (std::map<int, std::string> countMap{ {20, "zzh"}, {24, "张三"} }; auto [age, name] : countMap) {
		cout << age << "--" << name << endl;
	}
  C++知识库 最新文章
【C++】友元、嵌套类、异常、RTTI、类型转换
通讯录的思路与实现(C语言)
C++PrimerPlus 第七章 函数-C++的编程模块(
Problem C: 算法9-9~9-12:平衡二叉树的基本
MSVC C++ UTF-8编程
C++进阶 多态原理
简单string类c++实现
我的年度总结
【C语言】以深厚地基筑伟岸高楼-基础篇(六
c语言常见错误合集
上一篇文章      下一篇文章      查看所有文章
加:2022-02-19 00:58:09  更:2022-02-19 01:00:24 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/24 6:51:41-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码