Closed as duplicate of#105322
Description
This code below can work on gcc, but compile failed on clang++ (version=19.1.7).
#include <ranges>
struct my_vector
{
void emplace_back(auto&&...) { /*assume we do something here*/; }
};
int main ( )
{
auto my_vec = std::vector<int>() | std::ranges::to<my_vector>();
}
-
According to
https://en.cppreference.com/w/cpp/ranges/to
,- A container is
ranges::toable
(non-recursive) iff container implements- constructor
container(range&&)
, or - constructor
container(std::from_range_t, range&&)
, or - constructor
container(iterator, sentinel)
, or - satisfies concept
container-appendable
.
- constructor
- We now focus on the 4th case.
- In standard, A container is
container-appendable
iff container has member functionemplace_back()
orpush_back()
oremplace()
orinsert()
. - Then, we should use a for-loop to put the items into this container one-by-one.
- A container is
-
What libc++ did:
- in file
.../c++/v1/__ranges/to.h
- define
__container_insertable
concept, which only accepts a container who implements eitherpush_back()
orinsert()
. libc++ did not careemplace_back()
andemplace()
. - put items into container through
ranges::copy(__range, ranges::__container_inserter<range_reference_t<_Range>>(__result));
, which then callsback_insert_iterator
(if push_back) orinsert_iterator
(if insert). - back_insert_iterator has
operator=(container::value_type&&)
to do this push_back(), but what if the container(which might be trivial) who does not typedef value_type? same do insert_iterator.
- define
- in file
-
What is expected:
- Accepts all 4 kinds of "container-appendable" container.
- get rid of the fancy insert_iterator, an use a trivial for-loop to append elements one by one. (it only takes <= 5 lines)