【问题标题】:What is the status of std::ranges::split_view in C++20?C++20 中 std::ranges::split_view 的状态是什么?
【发布时间】:2021-12-15 11:07:50
【问题描述】:

根据https://en.cppreference.com/w/cpp/ranges/split_viewstd::ranges::split_view 必须从 C++20 开始可用。但是,同一页面上的示例在其文本中包含“C++23”:

#include <iostream>
#include <iomanip>
#include <ranges>
#include <string_view>
 
int main() {
    constexpr std::string_view words{"Hello-_-C++-_-23-_-!"};
    constexpr std::string_view delim{"-_-"};
    for (const std::string_view word : std::ranges::split_view(words, delim)) {
        std::cout << std::quoted(word) << ' ';
    }
}

GCC 和 MSVC 都拒绝接受这个 C++20 模式下的例子。 MSVC 特别打印:

The contents of <ranges> are available only in c++latest mode with concepts support;

https://gcc.godbolt.org/z/4fGGb3aqY

GCC 开始接受带有 -std=c++2b 命令行开关的代码(意味着即将推出的 C++23),而 MSVC 即使带有 /std:c++latest 选项也会报告错误

error C2440: 'initializing': cannot convert from 'std::ranges::split_view<std::basic_string_view<char,std::char_traits<char>>,std::basic_string_view<char,std::char_traits<char>>>::_Outer_iter<true>::value_type' to 'std::basic_string_view<char,std::char_traits<char>>'
note: No user-defined-conversion operator available that can perform this conversion, or the operator cannot be called

演示:https://gcc.godbolt.org/z/6z48Mz45j

C++20模式下的例子有什么问题,还是真的需要编译器的一些C++23特性?

【问题讨论】:

标签: c++ c++20 std-ranges c++23


【解决方案1】:

这个

for (const std::string_view word : std::ranges::split_view(words, delim)) {
    std::cout << std::quoted(word) << ' ';
}

需要解决一个 C++20 缺陷并实现一个 C++23 功能才能格式良好。

第一个是P2210,将原来的split_view重命名为lazy_split_view,并重新设计了新的split_view。其中一项改进是它的value_type 定义为subrange,这意味着当新的split_view 应用于contiguous_range 时,拆分子范围也将是contiguous_ranges。

因此,您的示例中的split_view(words, delim) 将返回subrange 的范围,该范围为contiguous_range

第二个是P1989,它为string_view添加了一个范围构造函数,这样它就可以接受contiguous_range并初始化它的成员。

由于它是 C++23 功能,这就是示例在其文本中包含“C++23”的原因。

【讨论】:

    猜你喜欢
    • 2020-10-01
    • 2020-01-11
    • 2021-02-18
    • 2021-01-04
    • 2020-03-19
    • 1970-01-01
    • 2020-08-06
    • 2021-05-23
    相关资源
    最近更新 更多