Search code examples
c++iteratorc++20std-ranges

Why can std::vector not accept iota_view iterators of type size_t?


The following code fails to compile when n is size_t but works fine for int and unsigned.

#include <vector>
#include <ranges>

int main() {
    size_t n = 1;
    auto view = std::ranges::iota_view{n, n};
    std::vector test(view.begin(), view.end()); //std::vector dislikes these iterators
}

https://godbolt.org/z/a3eGeMWqh


Solution

  • In order to solve the issue of integer overflow, the difference type of iota_view<uint64_t, uint64_t>::iterator will be __int128 in libstdc++, which is a integer-class type.

    An iterator with integer-class difference type is not a C++17 input iterator, so this makes vector template deduction fails because the iterator pair argument does not meet the requirements of __LegacyInputIterator (i.e. the difference type should only be a (signed) integral type).

    It's worth noting that __int128 is treated as integral type (which models std::integral) under GNU extensions, your code will be well-formed under the --std=gnu++20 flag.