You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用std::range懒生成std::string_view序列并分离声明定义?

用C++标准库Range实现懒加载的string_view序列

原始场景与需求

原有代码通过预定义数组生成std::vector<std::string_view>,实现如下:

static std::vector<std::string_view> x;

const char data[] = "1231234567812345";
const int offsets[] = { 0, 3, 11 };
const int sizes[] = { 3, 8, 5 };

const std::vector<std::string_view>& getRange()
{
    if (x.empty())
    {
        x.resize(sizeof(sizes) / sizeof(sizes[0]));
        for (size_t i = 0; i < x.size(); ++i)
            x[i] = std::string_view(data + offsets[i], data + offsets[i] + sizes[i]);
    }
    return x;
}

使用者仅需要该序列支持迭代、获取大小、operator[]访问,希望改用Range实现懒加载(类似ranges::iota),无需创建中间vector。

已实现的可行代码

你已经写出了等效功能的Range视图代码:

auto sv = [](int i) { return std::string_view(data + offsets[i], data + offsets[i] + sizes[i]); };
auto rangeView = std::views::iota(0u, sizeof(sizes) / sizeof(sizes[0])) | std::views::transform(sv);

问题:能否采用头文件声明+cpp文件定义的模式?

可以实现,具体步骤如下:

1. 头文件中声明函数

由于Range视图的类型是匿名模板类型,无法直接写出具体类型,可利用C++20的auto返回类型配合std::ranges::view约束:

// xxx.h
#include <ranges>
#include <string_view>

// 声明返回符合视图要求的Range对象
auto getRangeView() -> std::ranges::view auto;

2. cpp文件中实现函数

将数据源和视图生成逻辑放在cpp文件中,用匿名命名空间隔离全局变量避免污染:

// xxx.cpp
#include "xxx.h"

namespace {
// 把数据源放在匿名命名空间,仅当前cpp可访问
const char data[] = "1231234567812345";
const int offsets[] = { 0, 3, 11 };
const int sizes[] = { 3, 8, 5 };
} // 匿名命名空间

auto getRangeView() -> std::ranges::view auto {
    auto make_sv = [](int idx) {
        return std::string_view(data + offsets[idx], data + offsets[idx] + sizes[idx]);
    };
    return std::views::iota(0u, sizeof(sizes) / sizeof(sizes[0])) 
           | std::views::transform(make_sv);
}

补充说明

  • 该实现返回的Range视图是轻量对象,每次调用getRangeView()都会生成新的视图,但由于惰性求值特性,只有在迭代、访问元素时才会按需创建string_view,不会提前预存所有元素。
  • 视图支持迭代、获取大小(iota是sized range,transform后保留该属性)、operator[]访问(满足random_access_range概念,可直接用view[idx]或std::ranges::operator[])。

内容的提问来源于stack exchange,提问作者Pavel P

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.30 00:23:15