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.
queue constructorSection: 23.6 [container.adaptors] Status: C++11 Submitter: Howard Hinnant Opened: 2009-08-20 Last modified: 2016-01-28
Priority: Not Prioritized
View all other issues in [container.adaptors].
View all issues with C++11 status.
Discussion:
23.6.3.1 [queue.defn] has the following queue constructor:
template <class Alloc> explicit queue(const Alloc&);
This will be implemented like so:
template <class Alloc> explicit queue(const Alloc& a) : c(a) {}
The issue is that Alloc can be anything that a container will construct
from, for example an int. Is this intended to compile?
queue<int> q(5);
Before the addition of this constructor, queue<int>(5) would not compile.
I ask, not because this crashes, but because it is new and appears to be
unintended. We do not want to be in a position of accidently introducing this
"feature" in C++0X and later attempting to remove it.
I've picked on queue. priority_queue and stack have
the same issue. Is it useful to create a priority_queue of 5
identical elements?
[ Daniel, Howard and Pablo collaborated on the proposed wording. ]
[ 2009-10 Santa Cruz: ]
Move to Ready.
Proposed resolution:
[ This resolution includes a semi-editorial clean up, giving definitions to members which in some cases weren't defined since C++98. This resolution also offers editorially different wording for 976(i), and it also provides wording for 1196(i). ]
Change [ontainer.adaptor], p1:
The container adaptors each take a
Containertemplate parameter, and each constructor takes aContainerreference argument. This container is copied into theContainermember of each adaptor. If the container takes an allocator, then a compatible allocator may be passed in to the adaptor's constructor. Otherwise, normal copy or move construction is used for the container argument.[Note: it is not necessary for an implementation to distinguish between the one-argument constructor that takes aContainerand the one- argument constructor that takes an allocator_type. Both forms use their argument to construct an instance of the container. — end note]
Change [ueue.def], 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); : c(std::move(q.c)) {}
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(queue&&, const Alloc&);
queue& operator=(queue&& q); { c = std::move(q.c); return *this; }
bool empty() const { return c.empty(); }
...
};
Add a new section after 23.6.3.1 [queue.defn], [queue.cons]:
queueconstructors [queue.cons]explicit queue(const Container& cont);Effects: Initializes
cwithcont.explicit queue(Container&& cont = Container());Effects: Initializes
cwithstd::move(cont).queue(queue&& q)Effects: Initializes
cwithstd::move(q.c).For each of the following constructors, if
uses_allocator<container_type, Alloc>::valueisfalse, then the constructor shall not participate in overload resolution.template <class Alloc> explicit queue(const Alloc& a);Effects: Initializes
cwitha.template <class Alloc> queue(const container_type& cont, const Alloc& a);Effects: Initializes
cwithcontas the first argument andaas the second argument.template <class Alloc> queue(container_type&& cont, const Alloc& a);Effects: Initializes
cwithstd::move(cont)as the first argument andaas the second argument.template <class Alloc> queue(queue&& q, const Alloc& a);Effects: Initializes
cwithstd::move(q.c)as the first argument andaas the second argument.queue& operator=(queue&& q);Effects: Assigns
cwithstd::move(q.c).Returns:
*this.
Add to 23.6.4.2 [priqueue.cons]:
priority_queue(priority_queue&& q);Effects: Initializes
cwithstd::move(q.c)and initializescompwithstd::move(q.comp).For each of the following constructors, if
uses_allocator<container_type, Alloc>::valueisfalse, then the constructor shall not participate in overload resolution.template <class Alloc> explicit priority_queue(const Alloc& a);Effects: Initializes
cwithaand value-initializescomp.template <class Alloc> priority_queue(const Compare& compare, const Alloc& a);Effects: Initializes
cwithaand initializescompwithcompare.template <class Alloc> priority_queue(const Compare& compare, const Container& cont, const Alloc& a);Effects: Initializes
cwithcontas the first argument andaas the second argument, and initializescompwithcompare.template <class Alloc> priority_queue(const Compare& compare, Container&& cont, const Alloc& a);Effects: Initializes
cwithstd::move(cont)as the first argument andaas the second argument, and initializescompwithcompare.template <class Alloc> priority_queue(priority_queue&& q, const Alloc& a);Effects: Initializes
cwithstd::move(q.c)as the first argument andaas the second argument, and initializescompwithstd::move(q.comp).priority_queue& operator=(priority_queue&& q);Effects: Assigns
cwithstd::move(q.c)and assignscompwithstd::move(q.comp).Returns:
*this.
Change 23.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(stack&&, const Alloc&);
stack& operator=(stack&& s);
bool empty() const { return c.empty(); }
...
};
Add a new section after 23.6.6.2 [stack.defn], [stack.cons]:
stackconstructors [stack.cons]stack(stack&& s);Effects: Initializes
cwithstd::move(s.c).For each of the following constructors, if
uses_allocator<container_type, Alloc>::valueisfalse, then the constructor shall not participate in overload resolution.template <class Alloc> explicit stack(const Alloc& a);Effects: Initializes
cwitha.template <class Alloc> stack(const container_type& cont, const Alloc& a);Effects: Initializes
cwithcontas the first argument andaas the second argument.template <class Alloc> stack(container_type&& cont, const Alloc& a);Effects: Initializes
cwithstd::move(cont)as the first argument andaas the second argument.template <class Alloc> stack(stack&& s, const Alloc& a);Effects: Initializes
cwithstd::move(s.c)as the first argument andaas the second argument.stack& operator=(stack&& s);Effects: Assigns
cwithstd::move(s.c).Returns:
*this.