The list container implements a classic list data structure; unlike a C++ array or an STL vector, the objects it contains cannot be accessed directly (i.e., by subscript). (Be sure to study the requirements for objects that are stored in STL containers.) The list container is defined as a template class, meaning that it can be customized to hold objects of any type. Here is a simple example:
#include <list> // list class library using namespace std; ... // Now create a "list" object, specifying its content as "int". // The "list" class does not have the same "random access" capability // as the "vector" class, but it is possible to add elements at // the end of the list and take them off the front. list<int> list1; // Add some values at the end of the list, which is initially empty. // The member function "push_back" adds at item at the end of the list. int value1 = 10; int value2 = -3; list1.push_back (value1); list1.push_back (value2); list1.push_back (5); list1.push_back (1); // Output the list values, by repeatedly getting the item from // the "front" of the list, outputting it, and removing it // from the front of the list. cout << endl << "List values:" << endl; // Loop as long as there are still elements in the list. while (list1.size() > 0) { // Get the value of the "front" list item. int value = list1.front(); // Output the value. cout << value << endl; // Remove the item from the front of the list ("pop_front" // member function). list1.pop_front(); } |
Some commonly used member functions of the list class are:
size |
size_type size() const; // Loop as long as there are still elements in the list. while (list1.size() > 0) { ... } |
empty |
bool empty() const; if (list1.empty()) { ... } |
push_back |
void push_back(const T& x); list<int> nums; nums.push_back (3); nums.push_back (7); nums.push_front (10); // 10 3 7 |
front |
T& front(); list<int> nums; nums.push_back(33); nums.push_back(44); cout << nums.front() << endl; // 33 cout << nums.back() << endl; // 44 |
begin |
iterator begin(); |
end |
iterator end(); |
insert |
iterator insert(iterator position, const T& x); nums_iter = find (nums.begin(), nums.end(), 15); if (nums_iter != nums.end()) { nums_iter = nums.insert (nums_iter, -22); cout << "Inserted element " << (*nums_iter) << endl; } |
erase |
void erase(iterator position); nums.erase (nums.begin(), nums.end()); // Remove all elements; ... nums_iter = find(nums.begin(), nums.end(), 3); // Search the list. // If we found the element, erase it from the list. if (nums_iter != nums.end()) nums.erase(nums_iter); |
clear | void clear(); nums.clear(); // Remove all elements; |
---|---|
pop_front |
void pop_front(); while (list1.size() > 0) { ... list1.pop_front(); } |
remove |
void remove (const T& value); nums.remove(15); |
sort |
void sort(); nums.sort(); |
reverse |
void reverse(); nums.reverse(); |
In addition to these member functions, some STL algorithms (e.g., find) can be applied to the list container.
Some of the operators defined for the list container are:
= |
The assignment operator replaces the target list's contents with that of the source list: list<int> a; list<int> b; a.push_back(5); a.push_back(10); b.push_back(3); b = a; // The list b now contains two elements: 5, 10 |
== |
Tests whether two lists have the same content (element-by-element comparison for all elements). |
Note that there is no subscript operator for the list container, since random access to elements is not supported.
More information on iterators is available. Here, we will consider only a few simple uses of iterators with list containers.
A simple example of iterator use is traversing a list to print out its elements. The function output_int_list writes the elements of a list to an output stream and appends a specified delimiter string (here, just a newline character) after each element.
The list is passed by constant reference, instead of by value, so that it does not have to be copied (along with all its elements), but is still safe from modification. A const iterator (necessary because the argument is const) is used to traverse the list; each element is written to the specified stream.
#include <list> // list class library using namespace std; ... list<int> nums; nums.push_back (3); nums.push_back (7); nums.push_front (10); cout << endl << "List 'nums' now is:" << endl; output_int_list (nums, cout, "\n"); cout << endl; ... void output_int_list (const list<int>& lst, ostream& out_stream, const string& delim) { // Create constant iterator for list. list<int>::const_iterator iter; // Iterate through list and output each element. for (iter=lst.begin(); iter != lst.end(); iter++) { out_stream << (*iter) << delim; } } |
Just as the iterator's increment operator can be used to move forward in a list, the decrement operator may be used to "back up." Here, we search for the first occurrence of a certain element value, and then print the previous and following elements, if they exist. Note that we can copy the value of an iterator to "mark" a list position and that more than one iterator can be associated with a single container.
#include <list> // list class library #include <algorithm> // STL algorithms class library using namespace std; ... list<int> nums; list<int>::iterator nums_iter; nums.push_back (3); nums.push_back (7); nums.push_front (10); nums_iter = find(nums.begin(), nums.end(), 3); // Search the list. if (nums_iter != nums.end()) { cout << "Number " << (*nums_iter) << " found." << endl; // 3 // If found element is not first, print out previous. if (nums_iter != nums.begin()) { // Copy "found" iterator, and back up one position. list<int>::iterator prev_iter = nums_iter; cout << "Previous element is " << (*(--prev_iter)) << endl; } // Copy "found" iterator position, and move forward one position. list<int>::iterator next_iter = nums_iter; next_iter++; // If we didn't fall off the end, print out next element. if (next_iter != nums.end()) { cout << "Following element is " << (*next_iter) << endl; } } else { cout << "Number not found." << endl; } |
Iterator values may become invalid if the content of the associated container changes. For example, an iterator may specify the position of an element that is subsequently erased; in this case, the iterator value is no longer valid.
Copyright 2002 by Patrick Meier
Last updated on 26.08.2002 by Patrick Meier