Created on 2025-03-14.00:00:00 last changed 3 weeks ago
Proposed resolution:
This wording is relative to N5001.
[Drafting note: The proposed change also strips `const` from the value type of the `map`, 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 [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
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`.
Furthermore, both iterator and range deduction guides do not correctly handle iterators with a pair of references as value types, and deduce key or value type as reference, which is ill-formed:
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&>
History | |||
---|---|---|---|
Date | User | Action | Args |
2025-03-15 15:40:03 | admin | set | messages: + msg14680 |
2025-03-14 00:00:00 | admin | create |