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.
4223. Deduction guides for maps are mishandling tuples and referencesSection: 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_type remove_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_type range-key-type<Range> >, typename ranges::range_value_t<Range>::second_type range-mapped-type<Range> >; // exposition only
RetroSearch is an open source project built by @garambo | Open a GitHub Issue
Search and Browse the WWW like it's 1997 | Search results from DuckDuckGo
HTML:
3.2
| Encoding:
UTF-8
| Version:
0.7.4