简体   繁体   中英

C++ : STL Container adapters

In the below code, 'Second' is initialised to the copy of deque and 'fourth' by using underlying container. I feel glad if someone can explain me, When to initialize to the copy of a container and when to use an underlying container.

#include <iostream>       // std::cout
#include <deque>          // std::deque
#include <list>           // std::list
#include <queue>          // std::queue

int main ()
{
  std::deque<int> mydeck (3,100);        // deque with 3 elements
  std::list<int> mylist (2,200);         // list with 2 elements

  std::queue<int> first;                 // empty queue
  std::queue<int> second (mydeck);       // queue initialized to copy of deque

  std::queue<int,std::list<int> > third; 
  std::queue<int,std::list<int> > fourth (mylist);

  std::cout << "size of first: " << first.size() << '\n';
  std::cout << "size of second: " << second.size() << '\n';
  std::cout << "size of third: " << third.size() << '\n';
  std::cout << "size of fourth: " << fourth.size() << '\n';

  return 0;
}

When to initialize to the copy of a container and when to use an underlying container?

Both of these...

std::queue<int> second(mydeck);
std::queue<int,std::list<int> > fourth(mylist);

...construct and initialise a queue by copying elements from the container specified as constructor argument (ie mydeck and mylist respectively).

If you mean to ask why the second specifies a second template argument of std::list<int> , that's because std::queue can store the data in any container that provides the API functions it expects. From cppreference , that second template parameter is:

Container - The type of the underlying container to use to store the elements. The container must satisfy the requirements of SequenceContainer . Additionally, it must provide the following functions with the usual semantics:

    back()
    front()
    push_back()
    pop_front() 

The standard containers std::deque and std::list satisfy these requirements.

Of these, I'd guess that std::list would typically be more efficient for one or a very few elements (exactly where the cutoff is depends on object size, memory library performance characteristics, CPU cache sizes, system load etc. - it gets complicated), then std::deque will have better average performance and memory usage for larger numbers of elements (with fewer but larger dynamic memory allocations/deallocations). But even an educated guess can go badly wrong for some specific use cases - if you care enough to consider tuning this, you should measure performance with each candidate container, and your actual data and usage, to inform your decision. Having the container be a template parameter allows the programmer to choose what's best for their needs.

The parameter also has a default...

template <class T, class Container = std::deque<T>> class queue;

...so you only need to explicit specify a container if you're not happy to have it use a std::deque .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM