1

According to https://en.cppreference.com/w/cpp/ranges/split_view, std::ranges::split_view must be available since C++20. However the example on the same page contains "C++23" in its text:

#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) << ' ';
    }
}

Both GCC and MSVC refuse to accept this example in C++20 mode. MSVC in particular prints:

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

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

GCC starts accepting the code with -std=c++2b command-line switch (meaning forthcoming C++23), while MSVC even with /std:c++latest option reports the error

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

Demo: https://gcc.godbolt.org/z/6z48Mz45j

Is there something wrong with the example in C++20 mode, or it really requires some C++23 features from the compiler?

Fedor
  • 17,146
  • 13
  • 40
  • 131
  • 2
    Don't write `ranges::split_view`, write `views::split`. – Barry Nov 01 '21 at 14:29
  • 2
    Don't be mislead with _The contents of are available only in c++latest mode with concepts support;_, it does not mean that `` is not c++20, it means that MSVC STL implementers decided to wait till `` stabilize: https://github.com/microsoft/STL/issues/1814#issuecomment-845572895 – Alex Guteniev Nov 05 '21 at 11:50

1 Answers1

8

This

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

requires one C++20 defect to be resolved and one C++23 feature to be implemented to be well-formed.

The first one is P2210, which renamed the original split_view to lazy_split_view and redesigned the new split_view. One of the improvements is that its value_type is defined as subrange, which means that when the new split_view is applied to a contiguous_range, the splitting subranges will also be contiguous_ranges.

So split_view(words, delim) in your example will return a range of subrange which models contiguous_range.

The second one is P1989, which adds a range constructor to string_view so that it can accept a contiguous_range and initialize its members.

Since it is a C++23 feature, this is why the example contains "C++23" in its text.

康桓瑋
  • 33,481
  • 5
  • 40
  • 90