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

C++20中为何无法用|管道像其他视图函数一样调用views::reverse

问题原因

std::views::reverse本身是支持operator|链式调用的,你遇到的编译错误来自C++20下无参范围适配器的调用规则差异:

  • 需要传入配置参数的范围适配器(比如std::views::take(int)、std::views::transform(Callable)、std::views::filter(Callable)、std::views::take_while(Callable)):传入参数调用后会返回适配器闭包对象,该对象重载了operator|,可以和range完成链式拼接。
  • 不需要任何配置参数的范围适配器(C20标准下的std::views::reverse、std::views::join等):适配器本身就是合法的适配器闭包对象,不需要加括号调用。你代码中写的std::views::reverse()属于无参调用,C20标准库没有提供该重载,因此会触发编译错误。
实现方案

要实现输出b3、b4的效果,只需要去掉链式调用中reverse后面的空括号即可,修正后的完整代码如下:

#include <iostream>
#include <vector>
#include <string>
#include <ranges>

int main()
{
  using std::string;
  using std::cout, std::endl;
  
  const std::vector<string> vec = { "A", "B", "a", "b", "b2", "a2", "a3", "b3", "b4" };
  
  for (auto const& val : std::views::reverse(vec)
                      | std::views::take_while([](const string& s) {return s.size() > 0 && s[0] == 'b'; })
                      | std::views::reverse
    )
  {
    cout << val << endl;
  }
}

使用你原来的编译命令g++ -std=c++20 main.cpp -o main即可正常编译运行,执行逻辑为:

  1. 第一次reverse将原容器倒序,得到序列b4, b3, a3, a2, b2, b, a, B, A
  2. take_while从倒序序列开头截取首字符为b的元素,得到b4, b3
  3. 第二次reverse将截取后的序列再次倒序,得到目标序列b3, b4

注:C23标准为所有无参范围适配器补充了无参调用返回闭包的重载,在C23环境下写std::views::reverse()也可以正常通过编译,但C++20环境下必须省略空括号。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.28 22:30:55