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

### 1199. Missing extended copy constructor in container adaptors

Section: 22.6 [container.adaptors] Status: C++11 Submitter: Pablo Halpern Opened: 2009-08-26 Last modified: 2020-11-29

Priority: Not Prioritized

View all other issues in [container.adaptors].

View all issues with C++11 status.

Discussion:

`queue` has a constructor:

>     template <class Alloc>
>       queue(queue&&, const Alloc&);

but it is missing a corresponding constructor:

>     template <class Alloc>
>       queue(const queue&, const Alloc&);

The same is true of `priority_queue`, and `stack`. This "extended copy constructor" is needed for consistency and to ensure that the user of a container adaptor can always specify the allocator for his adaptor.

[ 2010-02-01 Moved to Tentatively Ready after 5 positive votes on c++std-lib. ]

Proposed resolution:

[ This resolution has been harmonized with the proposed resolution to issue 1194 ]

Change 22.6.4.1 [queue.defn], p1:

>     template <class T, class Container = deque<T> >
>     class queue {
>     public:
>       typedef typename Container::value_type      value_type;
>       typedef typename Container::reference       reference;
>       typedef typename Container::const_reference const_reference;
>       typedef typename Container::size_type       size_type;
>       typedef Container                           container_type;
>     protected:
>       Container c;

>     public:
>       explicit queue(const Container&);
>       explicit queue(Container&& = Container());
>       queue(queue&& q);

>       template <class Alloc> explicit queue(const Alloc&);
>       template <class Alloc> queue(const Container&, const Alloc&);
>       template <class Alloc> queue(Container&&, const Alloc&);
>       template <class Alloc> queue(const queue&, const Alloc&);
>       template <class Alloc> queue(queue&&, const Alloc&);
>       queue& operator=(queue&& q);

>       bool empty() const          { return c.empty(); }
>       ...
>     };

To the new section 22.6.4.2 [queue.cons], introduced in 1194, add:

>     template <class Alloc>
>       queue(const queue& q, const Alloc& a);

> > Effects: Initializes `c` with `q.c` as the first argument and `a` as the second argument.

Change 22.6.5 [priority.queue] as follows (I've an included an editorial change to move the poorly-placed move-assignment operator):

>     template <class T, class Container = vector<T>,
>               class Compare = less<typename Container::value_type> >
>     class priority_queue {
>     public:
>       typedef typename Container::value_type      value_type;
>       typedef typename Container::reference       reference;
>       typedef typename Container::const_reference const_reference;
>       typedef typename Container::size_type       size_type;
>       typedef          Container                  container_type;
>     protected:
>       Container c;
>       Compare comp;

>     public:
>       priority_queue(const Compare& x, const Container&);
>       explicit priority_queue(const Compare& x = Compare(), Container&& = Container());
>       template <class InputIterator>
>         priority_queue(InputIterator first, InputIterator last,
>                        const Compare& x, const Container&);
>       template <class InputIterator>
>         priority_queue(InputIterator first, InputIterator last,
>                        const Compare& x = Compare(), Container&& = Container());
>       priority_queue(priority_queue&&);
>       priority_queue& operator=(priority_queue&&);
>       template <class Alloc> explicit priority_queue(const Alloc&);
>       template <class Alloc> priority_queue(const Compare&, const Alloc&);
>       template <class Alloc> priority_queue(const Compare&,
>                                             const Container&, const Alloc&);
>       template <class Alloc> priority_queue(const Compare&,
>                                             Container&&, const Alloc&);
>       template <class Alloc> priority_queue(const priority_queue&, const Alloc&);
>       template <class Alloc> priority_queue(priority_queue&&, const Alloc&);

>       priority_queue& operator=(priority_queue&&);
>       ...
>     };

Add to 22.6.5.2 [priqueue.cons]:

>     template <class Alloc>
>       priority_queue(const priority_queue& q, const Alloc& a);

> > Effects: Initializes `c` with `q.c` as the first argument and `a` as the second argument, and initializes `comp` with `q.comp`.

Change 22.6.6.2 [stack.defn]:

>     template <class T, class Container = deque<T> >
>     class stack {
>     public:
>       typedef typename Container::value_type      value_type;
>       typedef typename Container::reference       reference;
>       typedef typename Container::const_reference const_reference;
>       typedef typename Container::size_type       size_type;
>       typedef Container                           container_type;
>     protected:
>       Container c;

>     public:
>       explicit stack(const Container&);
>       explicit stack(Container&& = Container());
>       stack(stack&& s);

>       template <class Alloc> explicit stack(const Alloc&);
>       template <class Alloc> stack(const Container&, const Alloc&);
>       template <class Alloc> stack(Container&&, const Alloc&);
>       template <class Alloc> stack(const stack&, const Alloc&);
>       template <class Alloc> stack(stack&&, const Alloc&);
>       stack& operator=(stack&& s);

>       bool empty() const          { return c.empty(); }
>       ...
>     };

To the new section 22.6.6.3 [stack.cons], introduced in 1194, add:

>     template <class Alloc>
>       stack(const stack& s, const Alloc& a);

> > Effects: Initializes `c` with `s.c` as the first argument and `a` as the second argument.