结构化绑定声明

结构化绑定声明,是指在一次声明中同时引入多个变量,同时绑定初始化表达式的各个子对象的语法形式。

结构化绑定声明使用auto来声明多个变量,所有变量都必须用中括号括起来。

cv-auto+引用 [变量1, 变量2, ... 变量n ] = 初始化表达式;
cv-auto+引用 [变量1, 变量2, ... 变量n ] (初始化表达式);
cv-auto+引用 [变量1, 变量2, ... 变量n ] {初始化表达式};
// 这里 cv-auto+引用 包含 auto, auto const, auto &, auto&& 等等形式

结构化绑定所声明的变量有两种形式:

  1. 非引用变量,此时初始化表达式对象需要拷贝一份,变量所绑定的是初始化表达式对象拷贝的各个子对象。
  2. 引用变量,此时初始化表达式对象不需要拷贝,变量所绑定的是初始化表达式对象本身的各个子对象。

结构化绑定中的初始化表达式有三种类型:

  1. 数组类型,此时变量所绑定的是数组的各个元素。
  2. pair tuple等支持 tuple_size<E> 的类型,此时变量所绑定的是 get<0>(e),get<1>(e),get<2>(e)...

    这里E是指类型,e是指对象。
  3. 带有 public 成员的结构类型,此时变量所绑定的是结构对象的各个 public 成员。

C++17代码

#include <iostream>
#include <utility>
#include <set>
#include <map> using namespace std; struct S {
int a, b, c;
}; map<string, int> get_map()
{
return {
{ "hello", 1 },
{ "world", 2 },
{ "it's", 3 },
{ "me", 4 },
};
} int main()
{
auto [a, b] = pair(2, "3"s);
cout << a << b << endl; // 23 set<string> myset;
if (auto [iter, success] = myset.insert("Hello"); success)
cout << *iter << endl; // Hello int arr[] = {1, 2, 3, 4};
const auto& [m1, m2, m3, m4] = arr;
cout << m1 << m2 << m3 << m4 << endl; //1234 S s = {4, 5, 6};
auto& [x, y, z] = s;
x = 0, y = 1, z = 2;
cout << s.a << s.b << s.c << endl; // 012 for (auto&& [k, v] : get_map())
cout << "k=" << k << " v=" << v << endl;
// k=hello v=1
// k=it's v=3
// k=me v=4
// k=world v=2
}

代码说明

  • 代码第24行采用结构化绑定声明了 int 类型的 a 和 string 类型的 b,分别绑定了初始化表达式中 pair 对象的 first 和 second。
  • 代码第28行采用结构化绑定声明了迭代类型的 iter 和 bool 类型的 success,分别绑定了初始化表达式中 pair 对象的 first 和 second。
  • 代码第32行采用结构化绑定声明了 const int& 类型的 m1 ~ m4,分别绑定了初始化表达式中 arr 数组的4个元素。
  • 代码第36行采用结构化绑定声明了 int& 类型的 x y z,分别绑定了初始化表达式中 s 对象的3个数据成员 a b c。
  • 代码第40行采用结构化绑定声明了 string&& 类型的 k 和 int 类型的 v,分别绑定了初始化表达式中 pair 对象的 first 和 second。

C++14等价代码

#include <iostream>
#include <utility>
#include <set>
#include <map> using namespace std; struct S {
int a, b, c;
}; map<string, int> get_map()
{
return {
{ "hello", 1 },
{ "world", 2 },
{ "it's", 3 },
{ "me", 4 },
};
} int main()
{
auto kv = make_pair(2, "3"s);
auto& a = kv.first; auto& b = kv.second;
cout << a << b << endl; // 23 set<string> myset;
set<string>::iterator iter;
bool success;
tie(iter, success) = myset.insert("Hello");
if (success)
cout << *iter << endl; // Hello int arr[] = {1, 2, 3, 4};
const auto &m1 = arr[0], &m2 = arr[1], &m3 = arr[2], &m4 = arr[3];
cout << m1 << m2 << m3 << m4 << endl; //1234 S s = {4, 5, 6};
auto &x = s.a, &y = s.b, &z = s.c;
x = 0, y = 1, z = 2;
cout << s.a << s.b << s.c << endl; // 012 for (auto&& kv : get_map()) {
auto&& k = forward<decltype(kv.first)>(kv.first);
auto&& v = forward<decltype(kv.second)>(kv.second);
cout << "k=" << k << " v=" << v << endl;
}
// k=hello v=1
// k=it's v=3
// k=me v=4
// k=world v=2
}

C++17尝鲜:结构化绑定声明(Structured Binding Declaration)的更多相关文章

  1. C++17结构化绑定

    动机 std::map<K, V>的insert方法返回std::pair<iterator, bool>,两个元素分别是指向所插入键值对的迭代器与指示是否新插入元素的布尔值, ...

  2. C++17尝鲜

    https://cloud.tencent.com/developer/article/1351910 [译]C++17,optional, any, 和 variant 的更多细节 用户261520 ...

  3. C++17尝鲜:在 if 和 switch 语句中进行初始化

    初始化语句 在C++17中,类似于 for 语句,在 if 和 switch 语句的判断条件之前也能加上初始化语句,语法形式如下: if (初始化语句; 条件) 语句 else 语句 switch ( ...

  4. 对结构化学习(structured learning)的理解

    接触深度学习以来一直接触的概念都是回归,分类,偶尔接触到结构化学习的概念,似懂非懂的糊弄过去,实在是不负责的表现 翻阅维基百科https://en.wikipedia.org/wiki/Structu ...

  5. 结构化数据(structured),半结构化数据(semi-structured),非结构化数据(unstructured)

    概念 结构化数据:即行数据,存储在数据库里,可以用二维表结构来逻辑表达实现的数据. 半结构化数据:介于完全结构化数据(如关系型数据库.面向对象数据库中的数据)和完全无结构的数据(如声音.图像文件等)之 ...

  6. 结构化学习(Structured Learning)

    本博客是针对李宏毅教授在youtube上上传的Machine Learning课程视频的学习笔记.课程链接 目录 引入 线性模型 结构化SVM 给序列贴标签 引入 我们之前学习到的学习模型的输入与输出 ...

  7. C++17尝鲜:变长 using 声明

    using 声明 先来看 using 声明在类中的应用: 代码1 #include <iostream> using namespace std; struct A { void f(in ...

  8. C++17尝鲜:variant

    variant variant 是 C++17 所提供的变体类型.variant<X, Y, Z> 是可存放 X, Y, Z 这三种类型数据的变体类型. 与C语言中传统的 union 类型 ...

  9. C++17尝鲜:编译期 if 语句

    Constexpr If(编译期 if 语句) 以 if constexpr 打头的 if 语句被称为 Constexpr If. Constexpr If 是C++17所引入的新的语法特性.它为C+ ...

随机推荐

  1. 不曾忘记的Vue.js

    马上2017年就结束了,虽然我因为目前的项目用不上你vue,但是我不曾忘记你,在时间缝隙的某一刹那,我再次将你拾起. vue.js全家桶:vue+ vuex+axios+vue-router+webp ...

  2. 关于jdango框架静态文件配置的问题

    一: 我们首先要知道什么是静态文件: 静态文件就是我们的HTML,css,图片等文件. 二: 我们要知道我们的Django框架是一个web服务器,那么web服务器,我们是通过一个url地址来访问它的, ...

  3. LOJ6268拆分数

    /* 相当于每种物品都有无限个的背包 毕竟考场上写exp是个比较危险的行为 对数据进行根号分治是个比较好的方法 对于小于等于根号的部分暴力背包转移 对于大于根号的 最多只会拿根号个 dp一下就好了 * ...

  4. three.js学习:初学three.js,从立方体开始

    目前three.js是浏览器展现3D效果的一个很强大的js工具,遗憾的是没有特别系统而全面的文档(threejs官方文档感觉有些缺漏,可以和WebGL中文网的threejs教程对比着看).好了,根据W ...

  5. 在Linux上git pull线上仓库代码时,出现error: Your local changes to the following files would be overwritten by merge

    在Windows上工作时未出现过该问题,于是通过命令: git diff 查看差异,得到结果: diff --git a/start_crons.sh b/start_crons.sh old mod ...

  6. liinux安装 mysql 及主从复制

    mariadb其实就是mysqlmysql已经被oracle收购,它即将闭源,马上要开始收费了因此还想免费试用开源的数据库mysql,就在centos7上,将mysql分支为mariadb 安装mar ...

  7. 【Selenium-WebDriver问题篇】Selenium实现元素的拖拽(java版)(转)

    https://blog.csdn.net/u010503127/article/details/51381284 Selenium实现元素的拖拽(java版) [前言] 自从淘宝网登陆页出现滑块验证 ...

  8. python生成器异步使用

    import dis,time # 反汇编 import threading def request(): print('start request') v = yield print(v) def ...

  9. asp 月末 月初

    上个月第一天:<%=dateadd("m",-1,year(date)&"-"&month(date)&"-1" ...

  10. Java 日期与数字转换

    package com.test; import org.apache.commons.lang.StringUtils; import org.junit.Test; import java.tex ...