专业的编程技术博客社区

网站首页 > 博客文章 正文

C++20尝鲜:结构化绑定(c++结构化程序设计)

baijin 2024-08-13 00:55:41 博客文章 7 ℃ 0 评论

放松结构化绑定定制点查找规则

P0961R1

结构化绑定的 lambda 捕获与存储类说明符

P1091R3
P1381R1

允许到可访问成员的结构化绑定

P0969R0

结构化绑定的Lambda捕获和存储类说明符

结构化绑定允许有[[maybe_unused]]属性、static和thread_local说明符。而且,现在可以在lambda中按值或按引用捕获它们。注意,绑定的位字段只能通过值捕获。

#include <iostream>
 
struct S{
    int a: 1;
    int b: 1;
    int c;
};

static auto [A,B,C] = S{};

void f(){
    [[maybe_unused]] thread_local auto [a,b,c] = S{0,0,1};
    [[maybe_unused]]auto l = [=](){
        return a + b + c;
    };
    std::cout << l() << std::endl; 
    [[maybe_unused]]auto m = [&](){
        // error, can't capture bit-fields 'a' and 'b' by-reference
        // return a + b + c;
        return c;
    };
}
 
int main()
{
    f();
    std::cout << A << std::endl; 
    return 0;
}
https://wandbox.org/nojs/gcc-head
https://wandbox.org/nojs/clang-head

放松结构化绑定自定义点查找规则

将类型分解为结构化绑定的一种方法是通过类似元组的 API。它由三个“函数”组成:std::tuple_element、std::tuple_size 和两个 get 选项:e.get<I>() 或 get<I>(e),其中第一个优先于第二个。也就是说,成员 get() 优先于非成员。想象一个类型有 get() 但它不适用于类似元组的 API,例如 std::shared_ptr::get()。这种类型无法分解,因为编译器会尝试使用成员 get() 并且它不起作用。现在,此规则已修复为仅当成员版本是模板且其第一个模板参数是非类型模板参数时才首选成员版本。

#include <iostream>
#include <memory>
struct X : private std::shared_ptr<int>{
    std::string payload {"hello"};
};

// due to new rules, this function is used instead of std::shared_ptr<int>::get
template<int N>
std::string& get(X& x) {
    if constexpr(N==0) return x.payload;
}

namespace std {
    template<>
    class tuple_size<X> 
        : public std::integral_constant<int, 1>
    {};
    
    template<>
    class tuple_element<0, X> {
    public:
        using type = std::string;
    };
}

void f(){
    X x;
    auto& [payload] = x;
    std::cout << payload << std::endl; 
}
 
int main()
{
    f();
    return 0;
}

允许结构化绑定到可访问的成员

此修复不仅允许对公共成员进行结构化绑定,还允许对结构化绑定声明上下文中可访问的成员进行结构化绑定。

#include <iostream>

struct A {
    friend void f();
private:
    int i;
};

void f() {
    A a;
    auto x = a.i;   // OK
    auto [y] = a;   // Ill-formed until C++20, now OK
}
 
int main()
{
    f();
    return 0;
}

Tags:

本文暂时没有评论,来添加一个吧(●'◡'●)

欢迎 发表评论:

最近发表
标签列表