Remember that a map can be interpreted as a relation between two collections.
In bimaps we have the freedom to change both collection types, imposing
constrains in each of them. Some insertions that we give for granted to
success in standard maps fails with bimaps. For example:

The insertion will only succeed if it is allowed by all views of the bimap. In the next snippet we define
the right collection as a multiset, when we try to insert the same two
elements the second insertion is allowed by the left map view because both
values are different and it is allowed by the right map view because it
is a non-unique collection type.

The relations stored in the Bimap will not be in most cases modifiable
directly by iterators because both sides are used as keys of key-based
sets. When a bimap<A,B> left view iterator is dereferenced
the return type is signature-compatible with a std::pair<constA,constB>.
However there are some collection types that are not key_based,
for example list_of. If a Bimap uses one of these collection types there
is no problem with modifying the data of that side. The following code
is valid:

set_of and unordered_set_of map views overload
operator[]
to retrieve the associated data of a given key only when the other collection
type is a mutable one. In these cases it works in the same way as the standard.

These functions look for a key and returns the associated data value, but
throws a std::out_of_range exception if the key is
not found.

In bimaps the constant version of these functions is given for set_of and unorderd_set_of
map views independently of the other collection type. The mutable version
is only provided when the other collection type is mutable.