结构化绑定

当在结构体或者类中使用结构化绑定的时候,需要有公开的访问权限,否则会导致编译失败。这条限制乍看是合理的,但是仔细想来却引入了一个相同条件下代码表现不一致的问题:

cpp 复制代码
struct A 
{
    friend void foo();
private:
    int i;
};

void foo() 
{
    A a{};
    auto x = a.i; // 编译成功
    auto [y] = a; // 编译失败
}

在上面这段代码中,foo是结构体A的友元函数,它可以访问A的私有成员i。但是,结构化绑定却失败了,这就明显不合理了。同样的问题还有访问自身成员的时候:

cpp 复制代码
class C 
{
    int i;
    void foo(const C& other) 
    {
        auto [x] = other; // 编译失败
    }
};

为了解决这类问题,C++20标准规定结构化绑定的限制不再强调必须为公开数据成员,编译器会根据当前操作的上下文来判断是否允许结构化绑定。幸运的是,虽然标准是2018年提出修改的,但在我实验的3种编译器上,无论是C++17还是C++20标准,以上代码都可以顺利地通过编译。

在C++20之前,lambda不能直接捕获结构化绑定的变量的

cpp 复制代码
#include <iostream>
#include <map>

using UeIdDu = int;
using UeCtx = int; //same as ueContext
std::map<UeIdDu, UeCtx> ueIds{{1, 10}, {2, 20}, {3, 30}};

int main()
{
        //solution 1
        for (const auto& [ueIdDu, ueCtx] : ueIds)
        {
	    const auto& ueId = ueIdDu; 
	    const auto& ctx = ueCtx; //sometime variable name is not good
	    [ueId, &ctx]() //C++ 17
	    {
	        std::cout << "ueIdDu: " << ueId << ", ueCtx: " << ctx << std::endl;
	    }();
	}
	//solution 2
	for (const auto& [ueIdDu, ueCtx] : ueIds)
	{
	    [ueIdDu = ueIdDu, &ueCtx = ueCtx]() //C++17
	    {
	        std::cout << "ueIdDu: " << ueIdDu << ", ueCtx: " << ueIdDu << std::endl;
	    }();
	}

    return 0;
}

c++20开始lambda可以捕获结构化绑定变量了:

cpp 复制代码
#include <iostream>
#include <map>

using UeIdDu = int;
using UeCtx = int;//same as ueContext

std::map<UeIdDu, UeCtx> ueIds{{1, 10}, {2, 20}, {3, 30}};

int main()
{
          //structure binding ueIdDu and ueCtx
	for (const auto& [ueIdDu, ueCtx] : ueIds)
	{
	    [ueIdDu, &ueCtx]()  //OK since C++20, C++17 clang failed!
	    {
	        std::cout << "ueIdDu: " << ueIdDu <<
                 ", ueCtx: " << ueCtx << std::endl;
	    }();
	}

    return 0;
}
相关推荐
Elaine20239112 天前
07 Lambda和StreamAPI
java·开发语言·lambda·stremapi
丶Darling.13 天前
Day41 | 动态规划 :完全背包应用 完全平方数&&单词拆分(类比爬楼梯)
算法·动态规划·dp·lambda·记忆化搜索·回溯·c++\
大福是小强16 天前
002-Kotlin界面开发之Kotlin旋风之旅
kotlin·函数式编程·lambda·语法·运算符重载·扩展函数
萧鼎1 个月前
【Python中的匿名函数】如何高效使用lambda表达式!
开发语言·python·lambda
I nedd more power1 个月前
Java JDK 23 新特性详解:功能、概念与用法
java·开发语言·lambda·泛型·jdk23·zgc垃圾回收器
亿牛云爬虫专家1 个月前
Scrapy的Lambda函数用法:简化数据提取与处理的技巧
爬虫·scrapy·数据分析·爬虫代理·lambda·代理ip·微博
一丝晨光2 个月前
继承、Lambda、Objective-C和Swift
开发语言·macos·ios·objective-c·swift·继承·lambda
钗头风2 个月前
(一)Lambda-Stream流
java·lambda
wumingxiaoyao2 个月前
AWS 实时数据流服务 Kinesis
云计算·big data·aws·lambda·kinesis
怒码ing3 个月前
浅谈维度建模、数据分析模型,何为数据仓库,与数据库的区别
大数据·数据仓库·实时数仓·lambda·数据湖·离线数仓·kappa