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.

### 2713. More missing allocator-extended constructors for unordered containers

Section: 22.5 [unord] Status: New Submitter: Billy Robert O'Neal III Opened: 2016-05-20 Last modified: 2020-11-29

Priority: 3

View all other issues in [unord].

View all issues with New status.

Discussion:

The resolution of LWG 2210 missed constructors accepting a range or initializer list and allocator.

Previous resolution [SUPERSEDED]:

> This wording is relative to N4582.

> 1. Add to the synopsis in 22.5.4.1 [unord.map.overview] p3:

>    >     namespace std {
>    >       template <class Key, class T,
>    >         class Hash = hash<Key>,
>    >         class Pred = std::equal_to<Key>,
>    >         class Allocator = std::allocator<std::pair<const Key, T> > > {
>    >       class unordered_map {
>    >       public:
>    >         […]
>    >         unordered_map(size_type n, const hasher& hf, const allocator_type& a)
>    >           : unordered_map(n, hf, key_equal(), a) { }
>    >         template <class InputIterator>
>    >           unordered_map(InputIterator f, InputIterator l, const allocator_type& a)
>    >           : unordered_map(f, l, see below, hasher(), key_equal(), a) { }
>    >         template <class InputIterator>
>    >           unordered_map(InputIterator f, InputIterator l, size_type n, const allocator_type& a)
>    >           : unordered_map(f, l, n, hasher(), key_equal(), a) { }
>    >         template <class InputIterator>
>    >           unordered_map(InputIterator f, InputIterator l, size_type n, const hasher& hf,
>    >                 const allocator_type& a)
>    >           : unordered_map(f, l, n, hf, key_equal(), a) { }
>    >         unordered_map(initializer_list<value_type> il, const allocator_type& a)
>    >           : unordered_map(il, see below, hasher(), key_equal(), a) { }
>    >         unordered_map(initializer_list<value_type> il, size_type n, const allocator_type& a)
>    >           : unordered_map(il, n, hasher(), key_equal(), a) { }
>    >         […]
>    >       };
>    >     }

> 2. Add to the synopsis in 22.5.5.1 [unord.multimap.overview] p3:

>    >     namespace std {
>    >       template <class Key, class T,
>    >         class Hash = hash<Key>,
>    >         class Pred = std::equal_to<Key>,
>    >         class Allocator = std::allocator<std::pair<const Key, T> > > {
>    >       class unordered_multimap {
>    >       public:
>    >         […]
>    >         unordered_multimap(size_type n, const hasher& hf, const allocator_type& a)
>    >           : unordered_multimap(n, hf, key_equal(), a) { }
>    >         template <class InputIterator>
>    >           unordered_multimap(InputIterator f, InputIterator l, const allocator_type& a)
>    >           : unordered_multimap(f, l, see below, hasher(), key_equal(), a) { }
>    >         template <class InputIterator>
>    >           unordered_multimap(InputIterator f, InputIterator l, size_type n, const allocator_type& a)
>    >           : unordered_multimap(f, l, n, hasher(), key_equal(), a) { }
>    >         template <class InputIterator>
>    >           unordered_multimap(InputIterator f, InputIterator l, size_type n, const hasher& hf,
>    >                 const allocator_type& a)
>    >           : unordered_multimap(f, l, n, hf, key_equal(), a) { }
>    >         unordered_multimap(initializer_list<value_type> il, const allocator_type& a)
>    >           : unordered_multimap(il, see below, hasher(), key_equal(), a) { }
>    >         unordered_multimap(initializer_list<value_type> il, size_type n, const allocator_type& a)
>    >           : unordered_multimap(il, n, hasher(), key_equal(), a) { }
>    >         […]
>    >       };
>    >     }

> 3. Add to the synopsis in 22.5.6.1 [unord.set.overview] p3:

>    >     namespace std {
>    >       template <class Key,
>    >         class Hash = hash<Key>,
>    >         class Pred = std::equal_to<Key>,
>    >         class Allocator = std::allocator<Key> > {
>    >       class unordered_set {
>    >       public:
>    >         […]
>    >         unordered_set(size_type n, const hasher& hf, const allocator_type& a)
>    >           : unordered_set(n, hf, key_equal(), a) { }
>    >         template <class InputIterator>
>    >           unordered_set(InputIterator f, InputIterator l, const allocator_type& a)
>    >           : unordered_set(f, l, see below, hasher(), key_equal(), a) { }
>    >         template <class InputIterator>
>    >           unordered_set(InputIterator f, InputIterator l, size_type n, const allocator_type& a)
>    >           : unordered_set(f, l, n, hasher(), key_equal(), a) { }
>    >         template <class InputIterator>
>    >           unordered_set(InputIterator f, InputIterator l, size_type n, const hasher& hf,
>    >                 const allocator_type& a)
>    >           : unordered_set(f, l, n, hf, key_equal(), a) { }
>    >         unordered_set(initializer_list<value_type> il, const allocator_type& a)
>    >           : unordered_set(il, see below, hasher(), key_equal(), a) { }
>    >         unordered_set(initializer_list<value_type> il, size_type n, const allocator_type& a)
>    >           : unordered_set(il, n, hasher(), key_equal(), a) { }
>    >         […]
>    >       };
>    >     }

> 4. Add to the synopsis in 22.5.7.1 [unord.multiset.overview] p3:

>    >     namespace std {
>    >       template <class Key,
>    >         class Hash = hash<Key>,
>    >         class Pred = std::equal_to<Key>,
>    >         class Allocator = std::allocator<Key> > {
>    >       class unordered_multiset {
>    >       public:
>    >         […]
>    >         unordered_multiset(size_type n, const hasher& hf, const allocator_type& a)
>    >           : unordered_multiset(n, hf, key_equal(), a) { }
>    >         template <class InputIterator>
>    >           unordered_multiset(InputIterator f, InputIterator l, const allocator_type& a)
>    >           : unordered_multiset(f, l, see below, hasher(), key_equal(), a) { }
>    >         template <class InputIterator>
>    >           unordered_multiset(InputIterator f, InputIterator l, size_type n, const allocator_type& a)
>    >           : unordered_multiset(f, l, n, hasher(), key_equal(), a) { }
>    >         template <class InputIterator>
>    >           unordered_multiset(InputIterator f, InputIterator l, size_type n, const hasher& hf,
>    >                 const allocator_type& a)
>    >           : unordered_multiset(f, l, n, hf, key_equal(), a) { }
>    >         unordered_multiset(initializer_list<value_type> il, const allocator_type& a)
>    >           : unordered_multiset(il, see below, hasher(), key_equal(), a) { }
>    >         unordered_multiset(initializer_list<value_type> il, size_type n, const allocator_type& a)
>    >           : unordered_multiset(il, n, hasher(), key_equal(), a) { }
>    >         […]
>    >       };
>    >     }

[2016-06, Oulu — Daniel comments and provides new wording]

During the LWG discussion of this issue it has been observed, that the interpretation of the embedded see below is not really clear and that we should split declaration and definition of the new overloads, so that we have a place that allows us to specify what "see below" stands for. In addition, the new wording wraps the "see below" as "`size_type(see below)`" to clarify the provided expression type, similar as we did for the default constructor of `unordered_map`.

[Oulu, 2016-06]

Alisdair to review wording.

Previous resolution [SUPERSEDED]:

> This wording is relative to N4594.

> 1. Add to the synopsis in 22.5.4.1 [unord.map.overview] p3:

>    >     namespace std {
>    >       template <class Key, class T,
>    >         class Hash = hash<Key>,
>    >         class Pred = std::equal_to<Key>,
>    >         class Allocator = std::allocator<std::pair<const Key, T> > > {
>    >       class unordered_map {
>    >       public:
>    >         […]
>    >         unordered_map(size_type n, const hasher& hf, const allocator_type& a)
>    >           : unordered_map(n, hf, key_equal(), a) { }
>    >         template <class InputIterator>
>    >           unordered_map(InputIterator f, InputIterator l, const allocator_type& a);
>    >         template <class InputIterator>
>    >           unordered_map(InputIterator f, InputIterator l, size_type n, const allocator_type& a)
>    >           : unordered_map(f, l, n, hasher(), key_equal(), a) { }
>    >         template <class InputIterator>
>    >           unordered_map(InputIterator f, InputIterator l, size_type n, const hasher& hf,
>    >                 const allocator_type& a)
>    >           : unordered_map(f, l, n, hf, key_equal(), a) { }
>    >         unordered_map(initializer_list<value_type> il, const allocator_type& a);
>    >         unordered_map(initializer_list<value_type> il, size_type n, const allocator_type& a)
>    >           : unordered_map(il, n, hasher(), key_equal(), a) { }
>    >         […]
>    >       };
>    >     }

> 2. Insert the following new prototype specification just after 22.5.4.2 [unord.map.cnstr] p2

>    >     template <class InputIterator>
>    >       unordered_map(InputIterator f, InputIterator l, const allocator_type& a)
>    >         : unordered_map(f, l, size_type(see below), hasher(), key_equal(), a) { }

>    >     unordered_map(initializer_list<value_type> il, const allocator_type& a)
>    >       : unordered_map(il, size_type(see below), hasher(), key_equal(), a) { }

>    > > -?- Remarks: The number of buckets is implementation-defined.

> 3. Add to the synopsis in 22.5.5.1 [unord.multimap.overview] p3:

>    >     namespace std {
>    >       template <class Key, class T,
>    >         class Hash = hash<Key>,
>    >         class Pred = std::equal_to<Key>,
>    >         class Allocator = std::allocator<std::pair<const Key, T> > > {
>    >       class unordered_multimap {
>    >       public:
>    >         […]
>    >         unordered_multimap(size_type n, const hasher& hf, const allocator_type& a)
>    >           : unordered_multimap(n, hf, key_equal(), a) { }
>    >         template <class InputIterator>
>    >           unordered_multimap(InputIterator f, InputIterator l, const allocator_type& a);
>    >         template <class InputIterator>
>    >           unordered_multimap(InputIterator f, InputIterator l, size_type n, const allocator_type& a)
>    >           : unordered_multimap(f, l, n, hasher(), key_equal(), a) { }
>    >         template <class InputIterator>
>    >           unordered_multimap(InputIterator f, InputIterator l, size_type n, const hasher& hf,
>    >                 const allocator_type& a)
>    >           : unordered_multimap(f, l, n, hf, key_equal(), a) { }
>    >         unordered_multimap(initializer_list<value_type> il, const allocator_type& a);
>    >         unordered_multimap(initializer_list<value_type> il, size_type n, const allocator_type& a)
>    >           : unordered_multimap(il, n, hasher(), key_equal(), a) { }
>    >         […]
>    >       };
>    >     }

> 4. Insert the following new prototype specification just after 22.5.5.2 [unord.multimap.cnstr] p2

>    >     template <class InputIterator>
>    >       unordered_multimap(InputIterator f, InputIterator l, const allocator_type& a)
>    >         : unordered_multimap(f, l, size_type(see below), hasher(), key_equal(), a) { }

>    >     unordered_multimap(initializer_list<value_type> il, const allocator_type& a)
>    >       : unordered_multimap(il, size_type(see below), hasher(), key_equal(), a) { }

>    > > -?- Remarks: The number of buckets is implementation-defined.

> 5. Add to the synopsis in 22.5.6.1 [unord.set.overview] p3:

>    >     namespace std {
>    >       template <class Key,
>    >         class Hash = hash<Key>,
>    >         class Pred = std::equal_to<Key>,
>    >         class Allocator = std::allocator<Key> > {
>    >       class unordered_set {
>    >       public:
>    >         […]
>    >         unordered_set(size_type n, const hasher& hf, const allocator_type& a)
>    >           : unordered_set(n, hf, key_equal(), a) { }
>    >         template <class InputIterator>
>    >           unordered_set(InputIterator f, InputIterator l, const allocator_type& a);
>    >         template <class InputIterator>
>    >           unordered_set(InputIterator f, InputIterator l, size_type n, const allocator_type& a)
>    >           : unordered_set(f, l, n, hasher(), key_equal(), a) { }
>    >         template <class InputIterator>
>    >           unordered_set(InputIterator f, InputIterator l, size_type n, const hasher& hf,
>    >                 const allocator_type& a)
>    >           : unordered_set(f, l, n, hf, key_equal(), a) { }
>    >         unordered_set(initializer_list<value_type> il, const allocator_type& a);
>    >         unordered_set(initializer_list<value_type> il, size_type n, const allocator_type& a)
>    >           : unordered_set(il, n, hasher(), key_equal(), a) { }
>    >         […]
>    >       };
>    >     }

> 6. Insert the following new prototype specification just after 22.5.6.2 [unord.set.cnstr] p2

>    >     template <class InputIterator>
>    >       unordered_set(InputIterator f, InputIterator l, const allocator_type& a)
>    >         : unordered_set(f, l, size_type(see below), hasher(), key_equal(), a) { }

>    >     unordered_set(initializer_list<value_type> il, const allocator_type& a)
>    >       : unordered_set(il, size_type(see below), hasher(), key_equal(), a) { }

>    > > -?- Remarks: The number of buckets is implementation-defined.

> 7. Add to the synopsis in 22.5.7.1 [unord.multiset.overview] p3:

>    >     namespace std {
>    >       template <class Key,
>    >         class Hash = hash<Key>,
>    >         class Pred = std::equal_to<Key>,
>    >         class Allocator = std::allocator<Key> > {
>    >       class unordered_multiset {
>    >       public:
>    >         […]
>    >         unordered_multiset(size_type n, const hasher& hf, const allocator_type& a)
>    >           : unordered_multiset(n, hf, key_equal(), a) { }
>    >         template <class InputIterator>
>    >           unordered_multiset(InputIterator f, InputIterator l, const allocator_type& a);
>    >         template <class InputIterator>
>    >           unordered_multiset(InputIterator f, InputIterator l, size_type n, const allocator_type& a)
>    >           : unordered_multiset(f, l, n, hasher(), key_equal(), a) { }
>    >         template <class InputIterator>
>    >           unordered_multiset(InputIterator f, InputIterator l, size_type n, const hasher& hf,
>    >                 const allocator_type& a)
>    >           : unordered_multiset(f, l, n, hf, key_equal(), a) { }
>    >         unordered_multiset(initializer_list<value_type> il, const allocator_type& a);
>    >         unordered_multiset(initializer_list<value_type> il, size_type n, const allocator_type& a)
>    >           : unordered_multiset(il, n, hasher(), key_equal(), a) { }
>    >         […]
>    >       };
>    >     }

> 8. Insert the following new prototype specification just after 22.5.7.2 [unord.multiset.cnstr] p2

>    >     template <class InputIterator>
>    >       unordered_multiset(InputIterator f, InputIterator l, const allocator_type& a)
>    >         : unordered_multiset(f, l, size_type(see below), hasher(), key_equal(), a) { }

>    >     unordered_multiset(initializer_list<value_type> il, const allocator_type& a)
>    >       : unordered_multiset(il, size_type(see below), hasher(), key_equal(), a) { }

>    > > -?- Remarks: The number of buckets is implementation-defined.

[2017-08-04, Daniel and Alisdair finetune wording]

We decided to improve the added Remarks: elements by changing from the previous form:

> Remarks: The number of buckets is implementation-defined.

to the more elaborate form:

> Remarks: The initial number of buckets supplied by the `size_type` argument is implementation-defined.

[2020-11-29; Reflector discussions]

It has been pointed out that this issue is related to LWG 1199, LWG 2210, and LWG 3506.

Proposed resolution:

This resolution is relative to N4687.

1. Add to the synopsis in 22.5.4.1 [unord.map.overview] p3:

   >     namespace std {
   >       template <class Key, class T,
   >         class Hash = hash<Key>,
   >         class Pred = std::equal_to<Key>,
   >         class Allocator = std::allocator<std::pair<const Key, T> > > {
   >       class unordered_map {
   >       public:
   >         […]
   >         unordered_map(size_type n, const hasher& hf, const allocator_type& a)
   >           : unordered_map(n, hf, key_equal(), a) { }
   >         template <class InputIterator>
   >           unordered_map(InputIterator f, InputIterator l, const allocator_type& a);
   >         template <class InputIterator>
   >           unordered_map(InputIterator f, InputIterator l, size_type n, const allocator_type& a)
   >           : unordered_map(f, l, n, hasher(), key_equal(), a) { }
   >         template <class InputIterator>
   >           unordered_map(InputIterator f, InputIterator l, size_type n, const hasher& hf,
   >                 const allocator_type& a)
   >           : unordered_map(f, l, n, hf, key_equal(), a) { }
   >         unordered_map(initializer_list<value_type> il, const allocator_type& a);
   >         unordered_map(initializer_list<value_type> il, size_type n, const allocator_type& a)
   >           : unordered_map(il, n, hasher(), key_equal(), a) { }
   >         […]
   >       };
   >     }

2. Insert the following new prototype specification just after 22.5.4.2 [unord.map.cnstr] p2

   >     template <class InputIterator>
   >       unordered_map(InputIterator f, InputIterator l, const allocator_type& a)
   >         : unordered_map(f, l, size_type(see below), hasher(), key_equal(), a) { }

   >     unordered_map(initializer_list<value_type> il, const allocator_type& a)
   >       : unordered_map(il, size_type(see below), hasher(), key_equal(), a) { }

   > > -?- Remarks: The initial number of buckets supplied by the `size_type` argument is implementation-defined.

3. Add to the synopsis in 22.5.5.1 [unord.multimap.overview] p3:

   >     namespace std {
   >       template <class Key, class T,
   >         class Hash = hash<Key>,
   >         class Pred = std::equal_to<Key>,
   >         class Allocator = std::allocator<std::pair<const Key, T> > > {
   >       class unordered_multimap {
   >       public:
   >         […]
   >         unordered_multimap(size_type n, const hasher& hf, const allocator_type& a)
   >           : unordered_multimap(n, hf, key_equal(), a) { }
   >         template <class InputIterator>
   >           unordered_multimap(InputIterator f, InputIterator l, const allocator_type& a);
   >         template <class InputIterator>
   >           unordered_multimap(InputIterator f, InputIterator l, size_type n, const allocator_type& a)
   >           : unordered_multimap(f, l, n, hasher(), key_equal(), a) { }
   >         template <class InputIterator>
   >           unordered_multimap(InputIterator f, InputIterator l, size_type n, const hasher& hf,
   >                 const allocator_type& a)
   >           : unordered_multimap(f, l, n, hf, key_equal(), a) { }
   >         unordered_multimap(initializer_list<value_type> il, const allocator_type& a);
   >         unordered_multimap(initializer_list<value_type> il, size_type n, const allocator_type& a)
   >           : unordered_multimap(il, n, hasher(), key_equal(), a) { }
   >         […]
   >       };
   >     }

4. Insert the following new prototype specification just after 22.5.5.2 [unord.multimap.cnstr] p2

   >     template <class InputIterator>
   >       unordered_multimap(InputIterator f, InputIterator l, const allocator_type& a)
   >         : unordered_multimap(f, l, size_type(see below), hasher(), key_equal(), a) { }

   >     unordered_multimap(initializer_list<value_type> il, const allocator_type& a)
   >       : unordered_multimap(il, size_type(see below), hasher(), key_equal(), a) { }

   > > -?- Remarks: The initial number of buckets supplied by the `size_type` argument is implementation-defined.

5. Add to the synopsis in 22.5.6.1 [unord.set.overview] p3:

   >     namespace std {
   >       template <class Key,
   >         class Hash = hash<Key>,
   >         class Pred = std::equal_to<Key>,
   >         class Allocator = std::allocator<Key> > {
   >       class unordered_set {
   >       public:
   >         […]
   >         unordered_set(size_type n, const hasher& hf, const allocator_type& a)
   >           : unordered_set(n, hf, key_equal(), a) { }
   >         template <class InputIterator>
   >           unordered_set(InputIterator f, InputIterator l, const allocator_type& a);
   >         template <class InputIterator>
   >           unordered_set(InputIterator f, InputIterator l, size_type n, const allocator_type& a)
   >           : unordered_set(f, l, n, hasher(), key_equal(), a) { }
   >         template <class InputIterator>
   >           unordered_set(InputIterator f, InputIterator l, size_type n, const hasher& hf,
   >                 const allocator_type& a)
   >           : unordered_set(f, l, n, hf, key_equal(), a) { }
   >         unordered_set(initializer_list<value_type> il, const allocator_type& a);
   >         unordered_set(initializer_list<value_type> il, size_type n, const allocator_type& a)
   >           : unordered_set(il, n, hasher(), key_equal(), a) { }
   >         […]
   >       };
   >     }

6. Insert the following new prototype specification just after 22.5.6.2 [unord.set.cnstr] p2

   >     template <class InputIterator>
   >       unordered_set(InputIterator f, InputIterator l, const allocator_type& a)
   >         : unordered_set(f, l, size_type(see below), hasher(), key_equal(), a) { }

   >     unordered_set(initializer_list<value_type> il, const allocator_type& a)
   >       : unordered_set(il, size_type(see below), hasher(), key_equal(), a) { }

   > > -?- Remarks: The initial number of buckets supplied by the `size_type` argument is implementation-defined.

7. Add to the synopsis in 22.5.7.1 [unord.multiset.overview] p3:

   >     namespace std {
   >       template <class Key,
   >         class Hash = hash<Key>,
   >         class Pred = std::equal_to<Key>,
   >         class Allocator = std::allocator<Key> > {
   >       class unordered_multiset {
   >       public:
   >         […]
   >         unordered_multiset(size_type n, const hasher& hf, const allocator_type& a)
   >           : unordered_multiset(n, hf, key_equal(), a) { }
   >         template <class InputIterator>
   >           unordered_multiset(InputIterator f, InputIterator l, const allocator_type& a);
   >         template <class InputIterator>
   >           unordered_multiset(InputIterator f, InputIterator l, size_type n, const allocator_type& a)
   >           : unordered_multiset(f, l, n, hasher(), key_equal(), a) { }
   >         template <class InputIterator>
   >           unordered_multiset(InputIterator f, InputIterator l, size_type n, const hasher& hf,
   >                 const allocator_type& a)
   >           : unordered_multiset(f, l, n, hf, key_equal(), a) { }
   >         unordered_multiset(initializer_list<value_type> il, const allocator_type& a);
   >         unordered_multiset(initializer_list<value_type> il, size_type n, const allocator_type& a)
   >           : unordered_multiset(il, n, hasher(), key_equal(), a) { }
   >         […]
   >       };
   >     }

8. Insert the following new prototype specification just after 22.5.7.2 [unord.multiset.cnstr] p2

   >     template <class InputIterator>
   >       unordered_multiset(InputIterator f, InputIterator l, const allocator_type& a)
   >         : unordered_multiset(f, l, size_type(see below), hasher(), key_equal(), a) { }

   >     unordered_multiset(initializer_list<value_type> il, const allocator_type& a)
   >       : unordered_multiset(il, size_type(see below), hasher(), key_equal(), a) { }

   > > -?- Remarks: The initial number of buckets supplied by the `size_type` argument is implementation-defined.