结构化绑定

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

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;
}
相关推荐
CoderMeijun10 天前
C++ 多线程进阶:Lambda、条件变量与死锁
c++·多线程·条件变量·lambda·死锁·生产者消费者
七夜zippoe12 天前
DolphinDB自定义函数:打造专属工具库
自定义·lambda·函数·模块化·工具库·dolphindb
审判长烧鸡15 天前
GO闭包【4】“普通闭包”与“循环闭包”之间捕获的核心区别
go·捕获·闭包
C雨后彩虹15 天前
Java Lambda & Stream 避坑指南:20个高频错误案例分析与修复
java·stream·lambda·并行流
TG_yunshuguoji16 天前
亚马逊云代理商:如何使用 CloudWatch 监控 AWS Lambda 函数日志?
云计算·aws·lambda·云服务器·cloudwatch
西西弗Sisyphus18 天前
Python Lambda 表达式等价普通函数实现
python·lambda
stevenzqzq25 天前
Kotlin 语法深度拆解:从 Java 匿名内部类到极简 Lambda 完整演进
java·kotlin·lambda
cnnews2 个月前
在AWS Lambda上部署 tokenizers
python·云计算·numpy·aws·lambda·onnxruntime·tokenizers
南部余额2 个月前
函数式接口 Lambda 表达式好搭档:Predicate、Function、Consumer、Supplier
java·开发语言·consumer·lambda·function·predicate·supplier
lightqjx2 个月前
【C++】C++11 - Lambda表达式+包装器
开发语言·c++·c++11·lambda·包装器