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

C++23:修改zip_view元素是否合规?并行排序双向量是否合法

C++23中可修改Range/View元素的场景与zip_view排序合法性问题

问题描述

我想明确C++23标准中允许修改range(或view)元素的具体场景。例如,我采用以下写法,按其中一个向量的值并行排序两个向量:

std::vector<size_t> keys{…};
std::vector<Foobar> values{…};

auto zip = std::ranges::views::zip(keys, values);
std::ranges::sort(zip, [](const auto & lhs, const auto & rhs) {
    return std::get<0>(lhs) < std::get<0>(rhs);
});

该写法在三大编译器及对应库实现中均可运行,但不确定是否符合标准。显然存在无法修改元素的view,比如std::transform_view。我不清楚标准如何界定view是否可修改,认为std::ranges::output_range是最佳判定依据,但cppreference显示std::zip_view并不满足该概念。请问上述排序写法是否违反标准,仅因编译器兼容才能运行?


解答

1. 标准对可修改Range/View的核心判定逻辑

C++标准中判断一个range/view是否允许修改元素,核心看两个点:

  • 其迭代器是否指向可修改、可交换的元素;
  • 对应的算法是否依赖该range的特定概念(比如sort依赖random_access_range和sortable,而非output_range)。

output_range概念针对的是"能通过迭代器直接赋值整个元素"的场景(即支持*it = value),但这并非所有修改操作的必要条件——像sort这类算法仅需要元素支持交换,而非直接赋值整个元素。

2. zip_view适配sort的合法性分析

std::zip_view的元素是引用类型的tuple(比如你的代码中是std::tuple<size_t&, Foobar&>),这种类型天然支持交换:当交换两个引用tuple时,会分别对每个成员引用指向的底层容器元素执行交换操作,完全符合sort需要的value_swappable要求。

cppreference标注zip_view不满足output_range是正确的——你无法直接给一个引用tuple赋值整个tuple值,但这和sort需要的交换能力毫无冲突,sort根本不需要用到output_range的赋值能力。

3. 你的代码完全符合C++23标准

三大编译器的实现是标准合规的:

  • zip_view满足random_access_range(因为被zip的两个vector都是随机访问range);
  • zip_view的元素满足value_swappable,符合sortable概念的要求;
  • 标准并未禁止对zip_view执行sort,只要它满足算法的概念前置条件即可。

4. 常见View的可修改性区分

  • transform_view:如果变换函数返回右值或不可修改的类型,元素无法修改/交换;若返回底层元素的引用,且原range可修改,则支持交换和修改。
  • filter_view:仅过滤原range的元素,只要原range可修改,它的元素就支持修改/交换。
  • zip_view:所有被zip的range可修改时,其元素(引用tuple)支持交换,可用于sort这类依赖交换的算法。

内容的提问来源于stack exchange,提问作者Lukas Barth

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.10 13:22:08