C++ 为什么可以';我用括号括起来的初始值设定项列表构造队列/堆栈吗?(C+;+;11)

C++ 为什么可以';我用括号括起来的初始值设定项列表构造队列/堆栈吗?(C+;+;11),c++,vector,c++11,initialization,queue,C++,Vector,C++11,Initialization,Queue,程序1: #include <iostream> #include <cstdlib> #include <vector> int main(){ //compiles successfully std::vector<int> vec{1,2,3,4,5}; return EXIT_SUCCESS; } #include <iostream> #include <cstdlib> #inc

程序1:

#include <iostream>
#include <cstdlib>
#include <vector>

int main(){

    //compiles successfully 
    std::vector<int> vec{1,2,3,4,5};

    return EXIT_SUCCESS;
}
#include <iostream>
#include <cstdlib>
#include <queue>

int main(){

    //compiler error
    std::queue<int> que{1,2,3,4,5};

    return EXIT_SUCCESS;
}
#包括
#包括
#包括
int main(){
//编译成功
向量向量{1,2,3,4,5};
返回退出成功;
}

程序2:

#include <iostream>
#include <cstdlib>
#include <vector>

int main(){

    //compiles successfully 
    std::vector<int> vec{1,2,3,4,5};

    return EXIT_SUCCESS;
}
#include <iostream>
#include <cstdlib>
#include <queue>

int main(){

    //compiler error
    std::queue<int> que{1,2,3,4,5};

    return EXIT_SUCCESS;
}
#包括
#包括
#包括
int main(){
//编译错误
队列{1,2,3,4,5};
返回退出成功;
}
错误消息:

main.cpp: In function ‘int main()’:
main.cpp:7:31: error: no matching function for call to ‘std::queue<int>::queue(<brace-enclosed initializer list>)’
main.cpp:7:31: note: candidates are:
/usr/include/c++/4.6/bits/stl_queue.h:141:7: note: std::queue<_Tp, _Sequence>::queue(_Sequence&&) [with _Tp = int, _Sequence = std::deque<int, std::allocator<int> >]
/usr/include/c++/4.6/bits/stl_queue.h:141:7: note:   candidate expects 1 argument, 5 provided
/usr/include/c++/4.6/bits/stl_queue.h:137:7: note: std::queue<_Tp, _Sequence>::queue(const _Sequence&) [with _Tp = int, _Sequence = std::deque<int, std::allocator<int> >]
/usr/include/c++/4.6/bits/stl_queue.h:137:7: note:   candidate expects 1 argument, 5 provided
/usr/include/c++/4.6/bits/stl_queue.h:92:11: note: std::queue<int>::queue(const std::queue<int>&)
/usr/include/c++/4.6/bits/stl_queue.h:92:11: note:   candidate expects 1 argument, 5 provided
/usr/include/c++/4.6/bits/stl_queue.h:92:11: note: std::queue<int>::queue(std::queue<int>&&)
/usr/include/c++/4.6/bits/stl_queue.h:92:11: note:   candidate expects 1 argument, 5 provided
main.cpp:在函数“int main()”中:
main.cpp:7:31:错误:调用'std::queue::queue()'时没有匹配的函数
main.cpp:7:31:注:候选人为:
/usr/include/c++/4.6/bits/stl_queue.h:141:7:注:std::queue::queue(_Sequence&)[with _Tp=int,_Sequence=std::deque]
/usr/include/c++/4.6/bits/stl_queue.h:141:7:注意:候选者需要1个参数,提供5个
/usr/include/c++/4.6/bits/stl_queue.h:137:7:注:std::queue::queue(const _Sequence&)[带_Tp=int,_Sequence=std::deque]
/usr/include/c++/4.6/bits/stl_queue.h:137:7:注意:候选者需要1个参数,提供5个
/usr/include/c++/4.6/bits/stl_queue.h:92:11:注意:std::queue::queue(const std::queue&)
/usr/include/c++/4.6/bits/stl_queue.h:92:11:注意:候选者需要1个参数,提供5个
/usr/include/c++/4.6/bits/stl_queue.h:92:11:注意:std::queue::queue(std::queue&)
/usr/include/c++/4.6/bits/stl_queue.h:92:11:注意:候选者需要1个参数,提供5个
问题:
为什么队列不能像向量一样初始化?
我想它们不是序列容器,但这又有什么关系呢?
我相信这是有充分理由的,但我找不到任何解释


gcc(Ubuntu/Linaro 4.6.1-9ubuntu3)4.6.1

std::queue
std::stack
实际上不是容器,它们被称为使用容器的容器适配器(默认情况下
std::deque
)。因此,您不能将其初始化为其他容器

编辑


为了使容器能够使用初始值设定项列表,它必须有一个以参数为参数的构造函数。容器适配器不会这样做。如果是故意的,或者是标准委员会的疏忽,这取决于任何人的解释。

我不认为这与作为容器适配器而不是容器有任何关系(尽管我承认我不确定为什么省略了正确的构造函数)

当您将带括号的初始值设定项列表与
std::vector
一起使用时,您使用的是这个(C++11中新增的)构造函数:

vector(initializer_list<T>, const Allocator& = Allocator());
采用初始化列表的构造函数显然不存在

我很确定,尽管是一个容器适配器,但如果需要的话,这样的构造函数将是微不足道的。举个例子:

#include <deque>
#include <initializer_list>
#include <iostream>

template <class T, class container=std::deque<T> >
class myqueue {
    container data;
public:
    explicit myqueue(std::initializer_list<T> t) : data(t) {}
    void pop() { data.pop_front(); }
    T front() const { return data.front(); }
    bool empty() const { return data.empty(); }
};

int main(){
    myqueue<int> data {1, 2, 3, 4};
    while (!data.empty()) {
        std::cout << data.front() << "\n";
        data.pop();
    }
    return 0;
}
虽然我没有使用任何其他编译器进行过测试,但我看不出任何其他编译器不能很好地使用它的原因(当然,前提是它们实现了必要的功能)

编辑:我只是在浏览委员会的文章,建议将iNITALIZER列表添加到C++(例如N1890、N1919、N2100、N2215、N2220),它看起来像是一个简单的疏忽。早期的许多论文更具概念性,但N2220为工作文件提供了相当多的建议语言。对于
std::array
(例如),它特别指出不需要更改。然后,它通过
deque
vector
[无序][多重](集合映射)
,并显示每个方向所需的更改--但在任何方向都没有提到堆栈或队列。没有建议添加对
std::initializer\u list
的支持,也没有(如
std::array
)对其省略的推理

我认为这是一个简单的疏忽,可能是因为两个原因:1)适配器几乎是容器,但不完全是容器;2)适配器类似乎没有被大量使用,所以忘记它们可能相当容易(当然,还有一个无处不在的第三个原因:大多数活跃的委员会成员工作过度)

Edit2:我应该再添加一个细节:由于
堆栈
队列
都可以接受另一个容器进行初始化,因此您可以很容易地执行以下操作:

std::stack<int> data(std::vector<int>{1,2,3,4});
std::堆栈数据(std::vector{1,2,3,4});
这有点冗长,但不太可能导致任何效率损失(容器将作为右值引用传递,因此其表示形式将被“窃取”而不是复制)。不过有一个警告:如果您使用的容器类型与容器适配器下的容器不匹配,则您将获得一个副本而不是移动(因此,可能会失去一些效率)。

队列q({1,2,3});

简而言之,
std::queue
std::stack
&
std::priorityqueue
是容器适配器,是使用其他标准库容器构建的容器。但是,它们可以使用初始化列表调用底层容器。为什么不这样做?我可以初始化std::deque。这些适配器不是吗几乎没有什么功能?还有,什么@RedXsaid@RedX在理论上,是的,适配器可能有初始化值列表构造函数,这些值传递给底层容器。如果你认为这是一个缺陷,你可以把它传递给C++委员会。好的,这应该是可接受的答案,因为已经接受了答案。的第一句话与这句话相矛盾,但这句话是正确的&直截了当的。您可以继承所需的容器适配器,并添加初始值设定项列表构造函数。使用C++11转发构造函数,这样您就不必实现基类构造函数。对于offerin来说,这是一个投票不足的答案两个可行的解决方案加上相应论文的摘要。你可以查看容器上的参考资料。你可能还想看看boost::assig
queue<int> q({1, 2, 3});