Program 1:
#include
#include
#include
int main(){
//compiles successfully
std::vect
I don't think it really has anything to do with being container adapters rather than containers (though I'll admit I'm uncertain exactly why the correct constructor is omitted).
When you use a braced initializer list with std::vector
, you're using this (new in C++11) constructor:
vector(initializer_list, const Allocator& = Allocator());
Looking at the definition of std::queue
, the available constructors are:
explicit queue(const Container&);
explicit queue(Container&& = Container());
template explicit queue(const Alloc&);
template queue(const Container&, const Alloc&);
template queue(Container&&, const Alloc&);
template queue(const queue&, const Alloc&);
template queue(queue&&, const Alloc&);
A constructor taking an initialization_list is conspicuously absent.
I'm quite certain that despite being a container adapter, such a constructor would be trivial if it was desired. Just for example:
#include
#include
#include
template >
class myqueue {
container data;
public:
explicit myqueue(std::initializer_list t) : data(t) {}
void pop() { data.pop_front(); }
T front() const { return data.front(); }
bool empty() const { return data.empty(); }
};
int main(){
myqueue data {1, 2, 3, 4};
while (!data.empty()) {
std::cout << data.front() << "\n";
data.pop();
}
return 0;
}
g++ 4.7 accepts this without any problems, and produces exactly the output you'd expect:
1
2
3
4
Although I haven't tested with any other compilers, I can't see any reason other compilers wouldn't work fine with this as well (provided they implement the necessary features, of course).
Edit: I just did some looking through the committee papers proposing the addition of initalizer_lists to C++ (e.g., N1890, N1919, N2100, N2215, N2220) and it looks to me like a simple oversight. Many of the earlier papers are more conceptual, but N2220 has a fair amount of proposed language for the working paper. For std::array
(for one example) it specifically points out that no change is needed. It then goes through deque
, vector
, [unordered_][multi_](set|map)
, and shows changes needed for each -- but no mention is made of stack or queue at all, in either direction. No proposal to add support for std::initializer_list
, nor (like std::array
) reasoning for their omission.
I'd conclude that it was a simple oversight, that probably slipped through for two reasons: 1) the adapters are almost, but not quite containers, and 2) the adapter classes don't seem to be used a whole lot, so forgetting about them was probably fairly easy (and, of course, the ever-pervasive third reason: most of the active committee members are horribly overworked).
Edit2: I should probably add one more detail: since stack
and queue
can both accept another container for the initialization, you can pretty easily do something like:
std::stack data(std::vector{1,2,3,4});
This is somewhat verbose, but unlikely to cause any loss of efficiency (the container will be passed as an rvalue reference, so its representation will be "stolen" instead of copied). There is one caveat though: if the type of container you use doesn't match the container underlying the container adapter, you'll get a copy rather than a move (and consequently, may lose some efficiency).