C++ 20新特性之结构化绑定

简介: 在C++ 20出现之前,当我们需要访问一个结构体或类的多个成员时,通常使用.或->操作符。对于复杂的数据结构,这种访问方式往往会显得冗长,也难以理解。C++ 20中引入的结构化绑定允许我们直接从一个聚合类型(比如:tuple、struct、class等)中提取出多个成员,并为它们分别命名。这一特性大大简化了对复杂数据结构的访问方式,使代码更加清晰、易读。

什么是结构化绑定

在C++ 20出现之前,当我们需要访问一个结构体或类的多个成员时,通常使用.或->操作符。对于复杂的数据结构,这种访问方式往往会显得冗长,也难以理解。C++ 20中引入的结构化绑定允许我们直接从一个聚合类型(比如:tuple、struct、class等)中提取出多个成员,并为它们分别命名。这一特性大大简化了对复杂数据结构的访问方式,使代码更加清晰、易读。


如何使用

使用结构化绑定比较简单,在声明变量时使用auto关键字和&符号,并用{}包含聚合类型的各个成员即可。其中,&符号为可选,表示引用。

首先,我们来看一下绑定元组的情况。在下面的示例代码中,我们通过std::make_tuple创建了一个包含人员信息的元组,并使用结构化绑定一次性解包为name、age两个变量。通过这种方式,数据访问变得简洁而高效。

#include <iostream>
#include <tuple>
int main()
{
    // 绑定到元组
    auto person = std::make_tuple("Mike", 18);
    const auto& [name, age] = person;
    std::cout << "Name: " << name << ", Age: " << age << std::endl;
    return 0;
}

接下来,我们学习下绑定数组和结构体的情况。在下面的示例代码中,我们将数组pnNumber赋值给对应的变量a、b和c,同时将结构体person赋值给对应的变量name和age。

#include <iostream>
#include <string>
struct TPersonInfo
{
    std::string name;
    int age;
};
int main()
{
    // 绑定到数组
    int pnNumber[] = {66, 77, 88};
    auto [a, b, c] = pnNumber;
    std::cout << a << ", " << b << ", " << c << std::endl;
    // 绑定到结构体
    TPersonInfo person{"Jack", 25};
    auto& [name, age] = person;
    std::cout << "Name: " << name << ", Age: " << age << std::endl;
    return 0;
}

除了上面介绍的这些,结构化绑定还支持直接绑定到匿名元组、匿名结构体和匿名联合。在下面的示例代码中,我们使用lambda表达式创建了一个临时的元组,并通过结构化绑定到匿名变量a和b上,避免了额外的变量声明。

#include <iostream>
int main()
{
    // 绑定到匿名元组
    auto [a, b] = []{ return std::make_tuple(66, 99); }();
    std::cout << a << ", " << b << std::endl;
    return 0;
}


注意事项

1、结构化绑定只能用于聚合类型,不能用于基本数据类型。

2、结构化绑定的变量是只读的,不能通过它们来修改原始数据。如果确实需要修改原始数据,可以使用引用或直接访问原始数据。

3、绑定顺序必须与聚合类型中元素的声明顺序保持一致。

4、如果不关心聚合类型中的某些成员,可以使用下划线_占位符来忽略不需要的成员。


相关文章
|
3月前
|
编译器 C++ 容器
【c++11】c++11新特性(上)(列表初始化、右值引用和移动语义、类的新默认成员函数、lambda表达式)
C++11为C++带来了革命性变化,引入了列表初始化、右值引用、移动语义、类的新默认成员函数和lambda表达式等特性。列表初始化统一了对象初始化方式,initializer_list简化了容器多元素初始化;右值引用和移动语义优化了资源管理,减少拷贝开销;类新增移动构造和移动赋值函数提升性能;lambda表达式提供匿名函数对象,增强代码简洁性和灵活性。这些特性共同推动了现代C++编程的发展,提升了开发效率与程序性能。
115 12
|
9月前
|
编译器 程序员 定位技术
C++ 20新特性之Concepts
在C++ 20之前,我们在编写泛型代码时,模板参数的约束往往通过复杂的SFINAE(Substitution Failure Is Not An Error)策略或繁琐的Traits类来实现。这不仅难以阅读,也非常容易出错,导致很多程序员在提及泛型编程时,总是心有余悸、脊背发凉。 在没有引入Concepts之前,我们只能依靠经验和技巧来解读编译器给出的错误信息,很容易陷入“类型迷路”。这就好比在没有GPS导航的年代,我们依靠复杂的地图和模糊的方向指示去一个陌生的地点,很容易迷路。而Concepts的引入,就像是给C++的模板系统安装了一个GPS导航仪
257 59
|
8月前
|
安全 编译器 C++
【C++11】新特性
`C++11`是2011年发布的`C++`重要版本,引入了约140个新特性和600个缺陷修复。其中,列表初始化(List Initialization)提供了一种更统一、更灵活和更安全的初始化方式,支持内置类型和满足特定条件的自定义类型。此外,`C++11`还引入了`auto`关键字用于自动类型推导,简化了复杂类型的声明,提高了代码的可读性和可维护性。`decltype`则用于根据表达式推导类型,增强了编译时类型检查的能力,特别适用于模板和泛型编程。
85 2
|
9月前
|
存储 编译器 C++
【C++】面向对象编程的三大特性:深入解析多态机制(三)
【C++】面向对象编程的三大特性:深入解析多态机制
|
9月前
|
存储 编译器 C++
【C++】面向对象编程的三大特性:深入解析多态机制(二)
【C++】面向对象编程的三大特性:深入解析多态机制
|
9月前
|
编译器 C++
【C++】面向对象编程的三大特性:深入解析多态机制(一)
【C++】面向对象编程的三大特性:深入解析多态机制
112 1
|
9月前
|
存储 编译器 C++
【C++】面向对象编程的三大特性:深入解析继承机制(三)
【C++】面向对象编程的三大特性:深入解析继承机制
117 0
|
9月前
|
编译器 C++
【C++】面向对象编程的三大特性:深入解析继承机制(二)
【C++】面向对象编程的三大特性:深入解析继承机制
|
5月前
|
编译器 C++ 开发者
【C++篇】深度解析类与对象(下)
在上一篇博客中,我们学习了C++的基础类与对象概念,包括类的定义、对象的使用和构造函数的作用。在这一篇,我们将深入探讨C++类的一些重要特性,如构造函数的高级用法、类型转换、static成员、友元、内部类、匿名对象,以及对象拷贝优化等。这些内容可以帮助你更好地理解和应用面向对象编程的核心理念,提升代码的健壮性、灵活性和可维护性。
|
1月前
|
人工智能 机器人 编译器
c++模板初阶----函数模板与类模板
class 类模板名private://类内成员声明class Apublic:A(T val):a(val){}private:T a;return 0;运行结果:注意:类模板中的成员函数若是放在类外定义时,需要加模板参数列表。return 0;
46 0