Created on 2023-11-24.00:00:00 last changed 8 months ago
Proposed resolution:
This wording is relative to N4964.
Modify [range.utility.conv.general] as indicated:
-4- Let
container-
be defined as follows:insertableappendabletemplate<class Container, class Ref> constexpr bool container-
insertableappendable = // exposition only requires(Container& c, Ref&& ref) { requires (requires { c.emplace_back(std::forward<Ref>(ref)); } || requires { c.push_back(std::forward<Ref>(ref)); } || requires { c.emplace(c.end(), std::forward<Ref>(ref)); } || requires { c.insert(c.end(), std::forward<Ref>(ref)); }); };-5- Let
container-
be defined as follows:inserterappendtemplate<class Container
, class Ref> constexpr auto container-inserterappend(Container& c) { // exposition onlyif constexpr (requires { c.push_back(declval<Ref>()); }) return back_inserter(c); else return inserter(c, c.end());return [&c]<class Ref>(Ref&& ref) { if constexpr (requires { c.emplace_back(declval<Ref>()); }) c.emplace_back(std::forward<Ref>(ref)); else if constexpr (requires { c.push_back(declval<Ref>()); }) c.push_back(std::forward<Ref>(ref)); else if constexpr (requires { c.emplace(c.end(), declval<Ref>()); }) c.emplace(c.end(), std::forward<Ref>(ref)); else c.insert(c.end(), std::forward<Ref>(ref)); }; };
Modify [range.utility.conv.to] as indicated:
(2.1.4) Otherwise, if
- —
constructible_from<C, Args...>
istrue
, and- —
container-
isinsertableappendable<C, range_reference_t<R>>true
:C c(std::forward<Args>(args)...); if constexpr (sized_range<R> && reservable-container<C>) c.reserve(static_cast<range_size_t<C>>(ranges::size(r))); ranges::
copyfor_each(r, container-inserterappend<range_reference_t<R>>(c));
[ Tokyo 2024-03-23; Status changed: Voting → WP. ]
[ 2024-03-11; Reflector poll ]
Set status to Tentatively Ready after six votes in favour during reflector poll.
[ 2023-1-26; Rename exposition-only concept and function after reflector discussion. ]
The exposition-only helper container-inserter
uses either
std::back_inserter
or std::inserter
. Both
std::back_insert_iterator
and std::insert_iterator
require C::value_type
to be a valid type, and we do not check
for that in container-insertable
.
The insert iterators can also incur a conversion to construct a
C::value_type
which then gets moved into the container.
Using emplace instead of insert would avoid that temporary object.
It's also possible (although arguably not worth caring about) that
range_value_t<C>
is not the same type as
C::value_type
, and that conversion to C::value_type
could be ill-formed (we only check that conversion from
range_reference_t<R>
to range_value_t<C>
is well-formed).
It seems preferable to remove the use of insert iterators, so that we don't need to check their requirements at all.
History | |||
---|---|---|---|
Date | User | Action | Args |
2024-04-02 10:29:12 | admin | set | messages: + msg14038 |
2024-04-02 10:29:12 | admin | set | status: voting -> wp |
2024-03-18 09:32:04 | admin | set | status: ready -> voting |
2024-03-11 21:44:56 | admin | set | messages: + msg13976 |
2024-03-11 21:44:56 | admin | set | status: new -> ready |
2023-11-26 15:39:20 | admin | set | messages: + msg13878 |
2023-11-24 17:39:40 | admin | set | messages: + msg13872 |
2023-11-24 00:00:00 | admin | create |