Skip to content

Performance issue in handling range iterators in vector constructor #1709

Description

@AlexBAV

STL loses iterator category when range iterators are passed to vector constructor. Consider the following code:

#include <ranges>
#include <vector>

namespace sr = std::ranges;
namespace rv = sr::views;

template<sr::random_access_range Range>
auto to_vector(Range &&range)
{
    return std::vector<sr::range_value_t<Range>>{sr::begin(range), sr::end(range)};
}

int main()
{
    std::vector a{ 1,2,3,4,5 };

    auto b = to_vector(a | rv::transform([](auto v) { return static_cast<float>(v); }));
}

Currently STL containers lack constructors accepting ranges. The above snippet, while explicitly requiring random access range (according to definition, a random access range "specifies a range whose iterator type satisfies random_access_iterator") eventually invokes vector's _Range_construct_or_tidy(_Iter _First, _Iter _Last, input_iterator_tag) instead of _Range_construct_or_tidy(_Iter _First, _Iter _Last, forward_iterator_tag), losing iterator category(?). This in turn calls emplace_back in a loop, not preallocating vector storage.

On the other hand, calling to_vector and passing a correctly dispatches to forward_iterator_tag version.

STL version

Microsoft Visual Studio Professional 2019 Preview
Version 16.9.0 Preview 5.0

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    externalThis issue is unrelated to the STL

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions