Search code examples
c++range-v3

Get the size of a join_view with range-v3


I am trying to get the size of a joint_view created from two std::vector. That should give me the sum of the sizes.

#include <range/v3/view/transform.hpp>
#include <range/v3/view/join.hpp>

#include <iostream>

int main()
{
    std::vector<int> s0;
    s0.push_back(0);
    s0.push_back(2);
…
    auto sc{s | 
            ranges::views::transform([](const auto &segment) {return segment;}) | ranges::views::join};

    auto nVertices{std::size(sc)};
    for (const auto &v : sc) {
        std::cout << v << "\n";
    

https://godbolt.org/z/o3Yzafrfj

However, I am getting a compile error:

<source>: In function 'int main()':
<source>:26:29: error: no matching function for call to 'size(ranges::join_view<ranges::transform_view<ranges::ref_view<std::vector<std::vector<int> > >, main()::<lambda(const auto:7&)> > >&)'
   26 |     auto nVertices{std::size(sc)};
...

Why can't I ask the size of the range in this case?


Solution

  • Some ranges don't provide a size() function, so calling std::size() (which really just calls the member function) is ineffective.

    With ranges of the Standard Library, you can call std::distance(std::cbegin(range), std::cend(range)) (resp. with begin and end when the ranges does not provide const iterators).

    With , the method is the same, but with ranges::distance.

    Note that since your range doesn't provide cbegin (resp. cend), you must use the non-const counterpart as:

    auto nVertices = ranges::distance(sc.begin(), sc.end());
    

    See it live here: https://godbolt.org/z/j4Eb4svrd