C++ STL源码剖析之容器配接器stack与queue、priority_queue

    下面本节带着这个问题来深入源码分析。

    在stack的源码中我们关注两点:- 默认为deque- 内部函数实现是调用_Sequence对应容器的函数。

    1. int test_stack() {
    2. cout<<"============test_stack============="<<endl;
    3. clock_t timeStart = clock();
    4. stack<int, list<int>> c;
    5. for (long i = 0; i < 100000; i++)
    6. c.push(i+1);
    7. cout << "stack.size()= " << c.size() << endl;
    8. cout << "stack.top()= " << c.top() << endl;
    9. c.pop();
    10. cout << "stack.size()= " << c.size() << endl;
    11. cout << "stack.top()= " << c.top() << endl;
    12. cout << "use stack milli-seconds : " << (clock() - timeStart) << endl;
    13. timeStart=clock();
    14. stack<int, deque<int>> c1;
    15. for (long i = 0; i < 100000; i++)
    16. c1.push(i+1);
    17. cout << "stack.size()= " << c1.size() << endl;
    18. cout << "stack.top()= " << c1.top() << endl;
    19. c1.pop();
    20. cout << "stack.size()= " << c1.size() << endl;
    21. cout << "stack.top()= " << c1.top() << endl;
    22. cout << "use stack milli-seconds : " << (clock() - timeStart) << endl;
    23. // vector可以作为stack的底层容器
    24. stack<int, vector<int>> c2;
    25. for (long i = 0; i < 100000; i++)
    26. c2.push(i+1);
    27. cout << "stack.size()= " << c2.size() << endl;
    28. cout << "stack.size()= " << c2.size() << endl;
    29. cout << "stack.top()= " << c2.top() << endl;
    30. cout << "use stack milli-seconds : " << (clock() - timeStart) << endl;
    31. }

    在queue的源码中我们关注两点:- 默认_Sequencedeque- 内部函数实现是调用_Sequence对应容器的函数。

    其对应的UML类图如下:

    queue_.png

    同理,优先队列则是使用vector作为默认容器。

    1. template<typename _Tp, typename _Sequence = vector<_Tp>,
    2. typename _Compare = less<typename _Sequence::value_type> >
    3. class priority_queue
    4. {
    5. public:
    6. typedef typename _Sequence::value_type value_type;
    7. typedef typename _Sequence::reference reference;
    8. typedef typename _Sequence::const_reference const_reference;
    9. typedef typename _Sequence::size_type size_type;
    10. typedef _Sequence container_type;
    11. protected:
    12. // See queue::c for notes on these names.
    13. _Sequence c;
    14. _Compare comp;
    15. public:
    16. reference
    17. top()
    18. {
    19. __glibcxx_requires_nonempty();
    20. return c.front();
    21. }
    22. void
    23. push(const value_type& __x)
    24. c.push_back(__x);
    25. }
    26. }

    测试这两个容器配接器支持的底层容器:

    对于queue底层容器可以是deque,也可以是list,但不能是vector,map,set,使用默认的deque效率在插入方面比其他容器作为底层要快!

    1. int test_priority_queue() {
    2. cout<<"============test_priority_queue============="<<endl;
    3. clock_t timeStart = clock();
    4. priority_queue<int, deque<int>> c1;
    5. for (long i = 0; i < 100000; i++) {
    6. c1.push(i+1);
    7. }
    8. cout << "stack.size()= " << c1.size() << endl;
    9. cout << "stack.top()= " << c1.top() << endl;
    10. c1.pop();
    11. cout << "stack.size()= " << c1.size() << endl;
    12. cout << "stack.top()= " << c1.top() << endl;
    13. cout << "use deque milli-seconds : " << (clock() - timeStart) << endl;
    14. priority_queue<int, vector<int>> c2;
    15. for (long i = 0; i < 100000; i++)
    16. c2.push(i+1);
    17. cout << "stack.size()= " << c2.size() << endl;
    18. cout << "stack.top()= " << c2.top() << endl;
    19. c2.pop();
    20. cout << "stack.size()= " << c2.size() << endl;
    21. cout << "stack.top()= " << c2.top() << endl;
    22. cout << "use stack milli-seconds : " << (clock() - timeStart) << endl;

    因此,stack、queue、priority_queue不被称为容器, 把它称为容器配接器。