c++c++20std-ranges

Count matching elements after splitting


I want to combine std::views::split or std::views::lazy_split with std::ranges::count but I cannot get it to work.

This is what I currently have:

std::string setting;
std::string extension;

const auto count = std::range::count(setting | std::views::split(' '), extension);

And unfortunately the MSVC error is not really helpful:

error C3889: call to object of class type 'std::ranges::_Count_fn': no matching call operator found

How can I count the elements that match extension after splitting (without having to store the parts into a container)?


Solution

  • The subranges after the split cannot be compared with string, so the constraint is not satisfied.

    You can use the projection to project them into string_views, which makes them comparable to strings:

    std::string setting;
    std::string extension;
    
    const auto count = std::ranges::count(
        setting | std::views::split(' '), 
        extension,
        [](auto r) { return std::string_view(r.data(), r.size()); }
    );
    

    Or with views::transform:

    const auto count = std::ranges::count(
        setting | std::views::split(' ')
                | std::views::transform(
                    [](auto r) { return std::string_view(r.data(), r.size()); }),
        extension
    );