结构化绑定

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

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;
}
相关推荐
程序员龙一4 天前
C++之lambda表达式使用解读
c++·lambda
闲人编程5 天前
Python在云计算中的应用:AWS Lambda函数实战
服务器·python·云计算·aws·lambda·毕设·codecapsule
闲人编程7 天前
使用Python进行量化交易入门
开发语言·python·统计分析·lambda·量化·codecapsule
程序猿编码18 天前
轻量级却实用:sigtrace 如何靠 ptrace 实现 Linux 信号的捕获与阻断(C/C++代码实现)
linux·c语言·c++·信号·捕获·ptrace
moringlightyn21 天前
c++11可变模版参数 emplace接口 新的类功能 lambda 包装器
开发语言·c++·笔记·其他·c++11·lambda·包装器
aaaweiaaaaaa2 个月前
c++基础学习(学习蓝桥杯 ros2有C基础可看)
c++·学习·蓝桥杯·lambda·ros2·智能指针·c++类
微风扬!2 个月前
C++ Lambda 表达式完整指南
c++·lambda
一叶飘零_sweeeet3 个月前
从繁琐到优雅:Java Lambda 表达式全解析与实战指南
java·lambda·java8
企鹅chi月饼3 个月前
c++中的Lambda表达式详解
c++·lambda
超级无敌永恒暴龙战士4 个月前
Java-Lambda表达式
java·lambda