Boost C++ Libraries Home Libraries People FAQ More

PrevUpHomeNext

One minute tutorial

What is a bimap?

The following code creates an empty bimap container:

typedef bimap<A,B> bm_type;
bm_type bm;

Given this code, the following is the complete description of the resulting bimap. [1]

simple.bimap

The relation class is a generalization of std::pair. The two values are named left and right to express the symmetry of this type.

The main difference between bimap views and their standard containers counterparts is that, because of the bidirectional nature of a bimap, the values stored in it can not be modified directly using iterators. For example, when a std::map<A,B> iterator is dereferenced the return type is std::pair<const A, B>, so the following code is valid: m.begin()->second = new_value;. However dereferencing a bimap<A,B>::left_iterator returns a type that is signature-compatible with a std::pair<const A, const B>.

That is more or less all that is needed to start using the bidirectional map. The following two lines must also be added:

#include <boost/bimap/bimap.hpp>
using namespace bimap;

A simple example

Here is a simple example of how to build and use a bimap. A description follows of how to enhance bidirectional maps to generate more powerful, scalable and readable code.

#include <iostream>

#include <boost/bimap/bimap.hpp>

int main()
{
    using namespace bimap;

    // Soccer World cup. (The results are not real)

    typedef bimap<std::string,int> results_bimap;
    typedef results_bimap::relation position;

    results_bimap results;
    results.insert( position("Argentina"    ,1) );
    results.insert( position("Spain"        ,2) );
    results.insert( position("Germany"      ,3) );
    results.insert( position("France"       ,4) );

    std::cout << "Countries names ordered by their final position:"
              << std::endl;

    for( results_bimap::right_iterator i    = results.right.begin(),
                                       iend = results.right.end() ;
         i != iend; ++i )
    {
        std::cout << i->first << ") " << i->second << std::endl;
    }

    std::cout << std::endl
              << "Countries names ordered alphabetically along with"
                 "their final position:"
              << std::endl;

    for( results_bimap::left_iterator  i    = results.left.begin(),
                                       iend = results.left.end() ;
         i != iend; ++i )
    {
        std::cout << i->first << " ends in position " << i->second << std::endl;
    }

}

The output of this program will be the following:

Countries names ordered by their final position:
1) Argentina
2) Spain
3) Germany
4) France

Countries names ordered alphabetically along with their final position:
Argentina ends in position 1
France ends in position 4
Germany ends in position 3
Spain ends in position 2

Continuing the journey

For information on function signatures, see any standard library documentation or read the reference section of this documentation.

[Caution] Caution

Be aware that a bidirectional map is only signature-compatible with standard containers. Some functions may give different results, such as in the case of inserting a pair into the left map where the second value conflicts with a stored relation in the container. The functions may be slower in a bimap because of the duplicated constraints. It is strongly recommended that you read The full tutorial if you intend to use a bimap in a serious project.



[1] A type is signature-compatible with other type if it has the same signature for functions and metadata. Preconditions, postconditions and the order of operations need not be the same.

Copyright © 2006 Matias Capeletto

PrevUpHomeNext