Search code examples
c++std-ranges

a more explicit type instead of auto for std::ranges::views result


auto is really nice to maintain a single definition and avoid some typing. It's also necessary for std::ranges::views. However, auto can make code harder to read it's too far from the defining type (particularly in code review). Replacing it with an explicit type can also validate that the type is what you expect (e.g. before passing it to a templated function and winding up in a world of template error message hurt). There needs to be a balance. Unfortunately, auto is necessary for views (I assume since the type is implementation dependent).

#include <ranges>

// Provided in some other header
template<class Range>
auto process(Range&& range)
{
    return range | std::ranges::views::transform(&Foo::i);
}

// main.cpp
struct Foo { int i; };

void func()
{
    Foo foos[4];

    // What is result and what can you do with it?
    auto result = process(foos);
}

Is there something I can replace auto with that makes the type a bit more clear?


Solution

  • auto can be constrained with C++ concepts

    template<typename Range, typename T>
    concept range_of = std::same_as<std::ranges::range_value_t<Range>, T>;
    
    ...
    
    range_of<int> auto result = process(foos);
    
    // range_of<float> auto result = process(foos); // error. thanks, compiler!
    

    I'm not aware of anything like range_of in the standard library, but it'd be nice if there were.