C++23 ranges::range_adaptor_closure:程序定义的范围适配器闭包的辅助类

一、背景介绍

C++23 引入了 std::ranges::range_adaptor_closure,这是一个辅助类模板,用于定义用户自定义的范围适配器闭包对象。这一特性主要来源于 P2387R3 提案,旨在支持用户定义的范围适配器与标准库视图适配器在管道表达式中的互操作。

二、ranges::range_adaptor_closure 的定义与要求

std::ranges::range_adaptor_closure 是一个类模板,用于确保用户定义的类型 T 是一个范围适配器闭包对象。具体要求如下:

  1. 单参数函数对象T 必须是一个单参数函数对象,接受一个范围作为参数。
  2. 单一基类T 必须恰好有一个公共基类 std::ranges::range_adaptor_closure<T>,且不能有其他类型的 std::ranges::range_adaptor_closure<U> 作为基类。
  3. 非范围类型T 本身不能是一个范围。
三、使用示例

以下是一个使用 std::ranges::range_adaptor_closure 的示例,展示如何定义一个简单的范围适配器闭包对象:

#include <ranges>
#include <string_view>
#include <iostream>

// 定义一个范围适配器闭包对象
struct Slice : std::ranges::range_adaptor_closure<Slice>
{
    std::size_t start = 0;
    std::size_t end = std::string_view::npos;

    constexpr std::string_view operator()(std::string_view sv) const
    {
        return sv.substr(start, end - start);
    }
};

int main()
{
    constexpr std::string_view str = "01234567";

    // 使用 Slice 作为普通函数对象
    constexpr Slice slicer{.start = 1, .end = 6};
    constexpr auto sv1 = slicer(str);
    std::cout << "sv1: " << sv1 << std::endl;

    // 使用 Slice 作为范围适配器闭包对象
    constexpr auto sv2 = str | slicer;
    std::cout << "sv2: " << sv2 << std::endl;

    // 范围适配器闭包可以组合
    constexpr auto slice_and_drop = slicer | std::views::drop(2);
    std::cout << "slice_and_drop: " << str | slice_and_drop << std::endl;
}
四、编译器支持情况

截至 2023 年 5 月,主流编译器对 std::ranges::range_adaptor_closure 的支持情况如下:

编译器支持情况
GCC libstdc++13(部分支持),14 完全支持
Clang libc++19 完全支持
MSVC STL19.34 完全支持
Apple Clang未明确支持
五、总结

C++23 的 std::ranges::range_adaptor_closure 提供了一种强大的机制,允许开发者定义自己的范围适配器闭包对象,并与标准库中的视图适配器无缝互操作。这一特性极大地增强了 C++ 范围库的灵活性和表达能力,使得范围操作更加简洁和高效。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

码事漫谈

感谢支持,私信“已赏”有惊喜!

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值