This page is a snapshot from the LWG issues list, see the Library Active Issues List for more information and the meaning of New status.
Section: 23.4.1 [associative.general] Status: New Submitter: Tomasz Kaminski Opened: 2025-03-14 Last modified: 2025-03-15
Priority: Not Prioritized
View all issues with New status.
Discussion:
The from_range
deduction guide for maps currently do not handle ranges of tuple of two elements:
std::vector<int> v;
auto zv = std::views::zip(v, v);
std::map m4(std::from_range, zv); // Ill-formed, no-deduction guide
This seems to be result of merge conflict between P2165 (Compatibility between tuple, pair and tuple-like objects)
and P1206R4 (Conversions from ranges to containers): The helper range-key-type
and
range-mapped-type
aliases introduced by the later use the old formulation of ::first_type
,
::second::type
instead of tuple_element
.
std::flat_map<int, float> fm; // iterator value_type is pair<int, float>
std::map m1(fm.begin(), fm.end()); // OK, deduces std::map<int, float>
auto tv = fm | std::views::transform(std::identity{}); // iterator value value_type is pair<int const&, float const&>
std::map m3(tv.begin(), tv.end()); // Ill-formed, deduces std::map<int const&, float&>
Proposed resolution:
This wording is relative to N5001.
[Drafting note: The proposed change also strips
const
from the value type of themap
, changing the behavior of previously working code:]std::pair<int const, float const> tp[2]; std::map m(std::begin(tp), std::end(tp)); // Was std::map<int, float const>, now std::map<int, float>
Modify 23.4.1 [associative.general] as indicated:
template<class InputIterator> using iter-value-type = typename iterator_traits<InputIterator>::value_type; // exposition only template<class InputIterator> using iter-key-type =remove_const_tremove_cvref_t< tuple_element_t<0, iter-value-type<InputIterator>>>; // exposition only template<class InputIterator> using iter-mapped-type = remove_cvref_t< tuple_element_t<1, iter-value-type<InputIterator>>>; // exposition only template<class InputIterator> using iter-to-alloc-type = pair< add_const_t<tuple_element_t<0, iter-value-type<InputIterator>>iter-key-type<InputIterator> >,tuple_element_t<1, iter-value-type<InputIterator>>iter-mapped-type<InputIterator> >; // exposition only template<ranges::input_range Range> using range-key-type =remove_const_t<typename ranges::range_value_t<Range>::first_type>remove_cvref_t<tuple_element_t<0, ranges::range_value_t<Range>>>; // exposition only template<ranges::input_range Range> using range-mapped-type =typename ranges::range_value_t<Range>::second_typeremove_cvref_t<tuple_element_t<1, ranges::range_value_t<Range>>>; // exposition only template<ranges::input_range Range> using range-to-alloc-type = pair<add_const_t<typename ranges::range_value_t<Range>::first_typerange-key-type<Range> >,typename ranges::range_value_t<Range>::second_typerange-mapped-type<Range> >; // exposition only