This page is a snapshot from the LWG issues list, see the Library Active Issues List for more information and the meaning of C++20 status.

### 3025. Map-like container deduction guides should use `pair<Key, T>`, not `pair<const Key, T>`

Section: 22.4.4.1 [map.overview], 22.4.5.1 [multimap.overview], 22.5.4.1 [unord.map.overview], 22.5.5.1 [unord.multimap.overview] Status: C++20 Submitter: Ville Voutilainen Opened: 2017-10-08 Last modified: 2021-02-25

Priority: 2

View all other issues in [map.overview].

View all issues with C++20 status.

Discussion:

With the deduction guides as specified currently, code like this doesn't work:

>     map m{pair{1, 1}, {2, 2}, {3, 3}};

Same problem occurs with `multimap`, `unordered_map` and `unordered_multimap`. The problem is in deduction guides like

>     template<class Key, class T, class Compare = less<Key>,
>               class Allocator = allocator<pair<const Key, T>>>
>     map(initializer_list<pair<const Key, T>>, Compare = Compare(),
>         Allocator = Allocator()) -> map<Key, T, Compare, Allocator>;

The `pair<const Key, T>` is not matched by a `pair<int, int>`, because `int` can't match a `const Key`. Dropping the `const` from the parameter of the deduction guide makes it work with no loss of functionality.

[2017-11-03, Zhihao Yuan comments]

The fix described here prevents

>     std::map m2{m0.begin(), m0.end()};

from falling back to direct-non-list-initialization. Treating a uniform initialization with >1 clauses of the same un-cvref type as `std::initializer_list` is the only consistent interpretation I found so far.

[2017-11 Albuquerque Wednesday night issues processing]

Priority set to 2

[2018-08-23 Batavia Issues processing]

Status to Tentatively Ready

[2018-11, Adopted in San Diego]

Proposed resolution:

This wording is relative to N4687.

1. Change 22.4.4.1 [map.overview] p3, class template `map` synopsis, as indicated:

   >     […]
   >     template<class Key, class T, class Compare = less<Key>,
   >              class Allocator = allocator<pair<const Key, T>>>
   >       map(initializer_list<pair<const Key, T>>, Compare = Compare(), Allocator = Allocator())
   >         -> map<Key, T, Compare, Allocator>;
   >     […]
   >     template<class Key, class T, class Allocator>
   >       map(initializer_list<pair<const Key, T>>, Allocator) -> map<Key, T, less<Key>, Allocator>;
   >     […]

2. Change 22.4.5.1 [multimap.overview] p3, class template `multimap` synopsis, as indicated:

   >     […]
   >     template<class Key, class T, class Compare = less<Key>,
   >              class Allocator = allocator<pair<const Key, T>>>
   >       multimap(initializer_list<pair<const Key, T>>, Compare = Compare(), Allocator = Allocator())
   >         -> multimap<Key, T, Compare, Allocator>;
   >     […]
   >     template<class Key, class T, class Allocator>
   >       multimap(initializer_list<pair<const Key, T>>, Allocator)
   >         -> multimap<Key, T, less<Key>, Allocator>;
   >     […]

3. Change 22.5.4.1 [unord.map.overview] p3, class template `unordered_map` synopsis, as indicated:

   >     […]
   >     template<class Key, class T, class Hash = hash<Key>,
   >              class Pred = equal_to<Key>, class Allocator = allocator<pair<const Key, T>>>
   >       unordered_map(initializer_list<pair<const Key, T>>, typename see below::size_type = see below, Hash = Hash(),
   >                     Pred = Pred(), Allocator = Allocator())
   >         -> unordered_map<Key, T, Hash, Pred, Allocator>;
   >     […]
   >     template<class Key, class T, typename Allocator>
   >       unordered_map(initializer_list<pair<const Key, T>>, typename see below::size_type,
   >                     Allocator)
   >         -> unordered_map<Key, T, hash<Key>, equal_to<Key>, Allocator>;

   >     template<class Key, class T, typename Allocator>
   >       unordered_map(initializer_list<pair<const Key, T>>, Allocator)
   >         -> unordered_map<Key, T, hash<Key>, equal_to<Key>, Allocator>;

   >     template<class Key, class T, class Hash, class Allocator>
   >       unordered_map(initializer_list<pair<const Key, T>>, typename see below::size_type, Hash,
   >                     Allocator)
   >         -> unordered_map<Key, T, Hash, equal_to<Key>, Allocator>;
   >     […]

4. Change 22.5.5.1 [unord.multimap.overview] p3, class template `unordered_multimap` synopsis, as indicated:

   >     […]
   >     template<class Key, class T, class Hash = hash<Key>,
   >              class Pred = equal_to<Key>, class Allocator = allocator<pair<const Key, T>>>
   >       unordered_multimap(initializer_list<pair<const Key, T>>,
   >                          typename see below::size_type = see below,
   >                          Hash = Hash(), Pred = Pred(), Allocator = Allocator())
   >         -> unordered_multimap<Key, T, Hash, Pred, Allocator>;
   >     […]
   >     template<class Key, class T, typename Allocator>
   >       unordered_multimap(initializer_list<pair<const Key, T>>, typename see below::size_type,
   >                          Allocator)
   >         -> unordered_multimap<Key, T, hash<Key>, equal_to<Key>, Allocator>;

   >     template<class Key, class T, typename Allocator>
   >       unordered_multimap(initializer_list<pair<const Key, T>>, Allocator)
   >         -> unordered_multimap<Key, T, hash<Key>, equal_to<Key>, Allocator>;

   >     template<class Key, class T, class Hash, class Allocator>
   >       unordered_multimap(initializer_list<pair<const Key, T>>, typename see below::size_type,
   >                          Hash, Allocator)
   >         -> unordered_multimap<Key, T, Hash, equal_to<Key>, Allocator>;
   >     […]