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

### 2210. Missing allocator-extended constructor for allocator-aware containers

Section: 22.3 [sequences], 22.4 [associative], 22.5 [unord] Status: C++14 Submitter: Jonathan Wakely Opened: 2012-11-01 Last modified: 2016-01-28

Priority: Not Prioritized

View all other issues in [sequences].

View all issues with C++14 status.

Discussion:

The `forward_list(size_type)` constructor has no allocator-extended equivalent, preventing the following code from compiling:

>     #include <forward_list>
>     #include <vector>
>     #include <scoped_allocator>

>     using namespace std;

>     int main()
>     {
>       using list = forward_list<int>;
>       vector<list, scoped_allocator_adaptor<list::allocator_type>> v;
>       v.emplace_back(1u);
>     }

The very same problem exists for all allocator-aware sequence containers.

In addition it exists for associative containers. For example, it's possible to construct `std::set<int>{0, 1, 2}` but not `std::set<int>{{0, 1, 2}, alloc}`, and possible to construct `std::set<int>{begin, end}` but not `std::set<int>{begin, end, alloc}`.

This makes the following program fail when `SCOPED` is defined:

>     #include <set>
>     #include <vector>
>     #include <scoped_allocator>

>     #if SCOPED
>     using A = std::scoped_allocator_adaptor<std::allocator<int>>;
>     #else
>     using A = std::allocator<int>;
>     #endif

>     int main()
>     {
>       int values[] = {0, 1, 2};
>       std::vector<std::set<int>, A> v;
>       v.emplace_back(std::begin(values), std::end(values));
>     }

[2013-03-15 Issues Teleconference]

Moved to Review.

Jonathan: There are lots of places where this is missing.

Howard: We should ping Pablo, this might be a deliberate design decision.

[2013-04-18, Bristol]

Proposed resolution:

This wording is relative to N3485.

1. Edit the synopsis in 22.3.8.1 [deque.overview]/2:

   >     namespace std {
   >       template <class T, class Allocator = allocator<T> >
   >       class deque {
   >       public:
   >         […]
   >         explicit deque(const Allocator& = Allocator());
   >         explicit deque(size_type n, const Allocator& = Allocator());
   >         […]
   >       };
   >     }

2. Edit 22.3.8.2 [deque.cons]/2:

   >     explicit deque(size_type n, const Allocator& = Allocator());

   > > -3- Effects: Constructs a `deque` with `n` default-inserted elements using the specified allocator.

3. Edit the synopsis in [forwardlist.overview]/3:

   >     namespace std {
   >       template <class T, class Allocator = allocator<T> >
   >       class forward_list {
   >       public:
   >         […]
   >         explicit forward_list(const Allocator& = Allocator());
   >         explicit forward_list(size_type n, const Allocator& = Allocator());
   >         […]
   >       };
   >     }

4. Edit [forwardlist.cons]/3:

   >     explicit forward_list(size_type n, const Allocator& = Allocator());

   > > -3- Effects: Constructs a `forward_list` object with `n` default-inserted elements using the specified allocator.

5. Edit the synopsis in 22.3.10.1 [list.overview]/2:

   >     namespace std {
   >       template <class T, class Allocator = allocator<T> >
   >       class list {
   >       public:
   >         […]
   >         explicit list(const Allocator& = Allocator());
   >         explicit list(size_type n, const Allocator& = Allocator());
   >         […]
   >       };
   >     }

6. Edit 22.3.10.2 [list.cons]/3:

   >     explicit list(size_type n, const Allocator& = Allocator());

   > > -3- Effects: Constructs a `list` with `n` default-inserted elements using the specified allocator.

7. Edit the synopsis in 22.3.11.1 [vector.overview]/2:

   >     namespace std {
   >       template <class T, class Allocator = allocator<T> >
   >       class vector {
   >       public:
   >         […]
   >         explicit vector(const Allocator& = Allocator());
   >         explicit vector(size_type n, const Allocator& = Allocator());
   >         […]
   >       };
   >     }

8. Edit 22.3.11.2 [vector.cons]/3:

   >     explicit vector(size_type n, const Allocator& = Allocator());

   > > -3- Effects: Constructs a `vector` with `n` default-inserted elements using the specified allocator.

9. Edit the synopsis in 22.3.12 [vector.bool]/1:

   >     namespace std {
   >       template <class Allocator> class vector<bool, Allocator> {
   >       class vector {
   >       public:
   >         […]
   >         explicit vector(const Allocator& = Allocator());
   >         explicit vector(size_type n, const Allocator& = Allocator());
   >         explicit vector(size_type n, const bool& value = bool(),
   >                         const Allocator& = Allocator());
   >         […]
   >       };
   >     }

10. Add to the synopsis in 22.4.4.1 [map.overview] p2:

    >     namespace std {
    >       template <class Key, class T, class Compare = less<Key>,
    >         class Allocator = allocator<pair<const Key, T> > > {
    >       class map {
    >       public:
    >         […]
    >         map(initializer_list<value_type>,
    >           const Compare& = Compare(),
    >           const Allocator& = Allocator());
    >         template <class InputIterator>
    >         map(InputIterator first, InputIterator last, const Allocator& a)
    >           : map(first, last, Compare(), a) { }
    >         map(initializer_list<value_type> il, const Allocator& a)
    >           : map(il, Compare(), a) { }
    >         ~map();
    >         […]
    >       };
    >     }

11. Add to the synopsis in 22.4.5.1 [multimap.overview] p2:

    >     namespace std {
    >       template <class Key, class T, class Compare = less<Key>,
    >         class Allocator = allocator<pair<const Key, T> > > {
    >       class multimap {
    >       public:
    >         […]
    >         multimap(initializer_list<value_type>,
    >           const Compare& = Compare(),
    >           const Allocator& = Allocator());
    >         template <class InputIterator>
    >         multimap(InputIterator first, InputIterator last, const Allocator& a)
    >           : multimap(first, last, Compare(), a) { }
    >         multimap(initializer_list<value_type> il, const Allocator& a)
    >           : multimap(il, Compare(), a) { }
    >         ~multimap();
    >         […]
    >       };
    >     }

12. Add to the synopsis in 22.4.6.1 [set.overview] p2:

    >     namespace std {
    >       template <class Key, class Compare = less<Key>,
    >         class Allocator = allocator<Key> > {
    >       class set {
    >       public:
    >         […]
    >         set(initializer_list<value_type>,
    >           const Compare& = Compare(),
    >           const Allocator& = Allocator());
    >         template <class InputIterator>
    >         set(InputIterator first, InputIterator last, const Allocator& a)
    >           : set(first, last, Compare(), a) { }
    >         set(initializer_list<value_type> il, const Allocator& a)
    >           : set(il, Compare(), a) { }
    >         ~set();
    >         […]
    >       };
    >     }

13. Add to the synopsis in 22.4.7.1 [multiset.overview] p2:

    >     namespace std {
    >       template <class Key, class Compare = less<Key>,
    >         class Allocator = allocator<Key> > {
    >       class multiset {
    >       public:
    >         […]
    >         multiset(initializer_list<value_type>,
    >           const Compare& = Compare(),
    >           const Allocator& = Allocator());
    >         template <class InputIterator>
    >         multiset(InputIterator first, InputIterator last, const Allocator& a)
    >           : multiset(first, last, Compare(), a) { }
    >         multiset(initializer_list<value_type> il, const Allocator& a)
    >           : multiset(il, Compare(), a) { }
    >         ~multiset();
    >         […]
    >       };
    >     }

14. 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(initializer_list<value_type>,
    >           size_type = see below,
    >           const hasher& hf = hasher(),
    >           const key_equal& eql = key_equal(),
    >           const allocator_type& a = allocator_type());
    >         unordered_map(size_type n, const allocator_type& a)
    >           : unordered_map(n, hasher(), key_equal(), a) { }
    >         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, 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, size_type n, const allocator_type& a)
    >           : unordered_map(il, n, hasher(), key_equal(), a) { }
    >         unordered_map(initializer_list<value_type> il, size_type n, const hasher& hf,
    >     	  const allocator_type& a)
    >           : unordered_map(il, n, hf, key_equal(), a) { }
    >         ~unordered_map();
    >         […]
    >       };
    >     }

15. 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(initializer_list<value_type>,
    >           size_type = see below,
    >           const hasher& hf = hasher(),
    >           const key_equal& eql = key_equal(),
    >           const allocator_type& a = allocator_type());
    >         unordered_multimap(size_type n, const allocator_type& a)
    >           : unordered_multimap(n, hasher(), key_equal(), a) { }
    >         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, 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, size_type n, const allocator_type& a)
    >           : unordered_multimap(il, n, hasher(), key_equal(), a) { }
    >         unordered_multimap(initializer_list<value_type> il, size_type n, const hasher& hf,
    >     	  const allocator_type& a)
    >           : unordered_multimap(il, n, hf, key_equal(), a) { }
    >         ~unordered_multimap();
    >         […]
    >       };
    >     }

16. 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(initializer_list<value_type>,
    >           size_type = see below,
    >           const hasher& hf = hasher(),
    >           const key_equal& eql = key_equal(),
    >           const allocator_type& a = allocator_type());
    >         unordered_set(size_type n, const allocator_type& a)
    >           : unordered_set(n, hasher(), key_equal(), a) { }
    >         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, 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, size_type n, const allocator_type& a)
    >           : unordered_set(il, n, hasher(), key_equal(), a) { }
    >         unordered_set(initializer_list<value_type> il, size_type n, const hasher& hf,
    >     	  const allocator_type& a)
    >           : unordered_set(il, n, hf, key_equal(), a) { }
    >         ~unordered_set();
    >         […]
    >       };
    >     }

17. 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(initializer_list<value_type>,
    >           size_type = see below,
    >           const hasher& hf = hasher(),
    >           const key_equal& eql = key_equal(),
    >           const allocator_type& a = allocator_type());
    >         unordered_multiset(size_type n, const allocator_type& a)
    >           : unordered_multiset(n, hasher(), key_equal(), a) { }
    >         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, 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, size_type n, const allocator_type& a)
    >           : unordered_multiset(il, n, hasher(), key_equal(), a) { }
    >         unordered_multiset(initializer_list<value_type> il, size_type n, const hasher& hf,
    >     	  const allocator_type& a)
    >           : unordered_multiset(il, n, hf, key_equal(), a) { }
    >         ~unordered_multiset();
    >         […]
    >       };
    >     }