-
Notifications
You must be signed in to change notification settings - Fork 1.5k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Performance issue in handling range iterators in vector constructor #1709
Comments
Some observations, I think @CaseyCarter will know better
template <_Has_member_iterator_category _Traits, class _Base>
struct _Category_base<_Traits, _Base> {
// clang-format on
using iterator_category =
conditional_t<is_lvalue_reference_v<invoke_result_t<_Fn&, range_reference_t<_Base>>>,
conditional_t<derived_from<typename _Traits::iterator_category, contiguous_iterator_tag>,
random_access_iterator_tag, typename _Traits::iterator_category>,
input_iterator_tag>;
}; The provided iterators are definitely random_access iterators, but look at the first condition: is_lvalue_reference_v<invoke_result_t<_Fn&, range_reference_t<_Base>>> Your lambda function is taking the content by value and returning it by value. I think this is the crux and I am unsure how you would solve it in this specific use case where you cast to a different type |
This is a simplified version for illustration. The actual code snippet it was taken from has a different code path for I need to think about your second point on See also https://godbolt.org/z/c3sY6j: it confirms that iterator taken from transform view range satisfies the |
@AlexBAV, thanks for the report. This is a well-known issue in WG21, we just didn't have time to gel a good solution for "materializing" views into containers. There's at least one proposal in progress to fix this problem (WG21-P1206 " In any case, I don't think there's anything we can do here in the STL without direction from WG21. |
Can't we just use |
|
The only constraint that I could find, that |
STL loses iterator category when range iterators are passed to vector constructor. Consider the following code:
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 callsemplace_back
in a loop, not preallocating vector storage.On the other hand, calling
to_vector
and passinga
correctly dispatches toforward_iterator_tag
version.STL version
The text was updated successfully, but these errors were encountered: