[bimap] Creating a bimap fom a std::map

I would have thought, naively enough, that one of the common uses of a
bimap was that one should be able to create a bimap from a std::map as
long as the relation between the two types was unique both ways. I was
disconcerted when I did not see a bimap constructor that accepted a
std::map of the same types, but then I saw the constructor which takes
two iterators and decided to try that, like so:
std::map

Hello Edward,
On Wed, Nov 25, 2009 at 10:40 AM, Edward Diener
Yes, this is a very common scenario.
The library does not have this constructor by design. A bimap can be
viewed as a map (if you choose the left or the right view) but it is
not directly compatible with a map to enforce the idea that both
values are at the same level in the container. You explicitly have to
choose the left view to do what you are trying to achieve:
std::map

Matias Capeletto wrote:
My opinion is that you should have a constructor which takes a std::map,
where the types of the map are the types of the bimap. If the types of
the map are the same as the types of the bimap, then the constructor
should do exactly the equivalent to what you show just above. If the
types of the map are the reverse of the types of the bimap, then the
constructor should be the equivalent of:
std::mapstd::string,int myMap;
// ... fill myMap
boost::bimap
Yes, of course. See above. I just do not agree that not providing the obvious constructor is good because it "maintains symmetry". Many things in programming are good because they provide ease-of-use and my suggestion is an obvious case of that.

On Wed, Nov 25, 2009 at 1:24 PM, Edward Diener
I understand your easy-of-use point, but you have just wrote down here why it is not a good idea to provide this constructor. Not only it breaks the symmetry, the real problem is that following your idea of automatic conversion between pairs and relations we bump into ambiguities. Imagine you now have a bimap, and you use your constructor with a map... it is not clear which side is the left and which side is the right. I thought about this issues and it was decided that it is better not to surprise the user with this kind of ambiguities. Thanks for your suggestion and interest. Best regards Matias

Matias Capeletto wrote:
Are you saying that if I insert map items on the left side of a bimap I can not access them from the right side of the bimap, or vice versa ? That would seem to make the bimap fairly useless. If not, in your example of bimap and map it should make no difference whatever into which side the map pairs are originally inserted.

On Wed, Nov 25, 2009 at 6:08 PM, Edward Diener
I am not saying that.
The problem is that If you have a std::map

Matias Capeletto wrote:
But if I do the above I can still access the bimap from either the left or right views. So it little matters which one I use to actually insert my map entries. Whether I go: bm.left.insert( m.begin(), m.end() ); or bm.right.insert( m.begin(), m.end() ); ,when both types are the same, is totally irrelevant to further use of the bimap. Is this not correct ? So therefore if you create a bimap constructor which takes a map, and both types are exactly the same, it is irrelevant if internally you use bm.left.insert( m.begin(), m.end() ); or bm.right.insert( m.begin(), m.end() ); to populate the bimap. Therefore your argument that having to decide how to populate the bimap from a map, when both types are the same, is a reason not to create a constructor which takes a map is not valid to me.

On Wed, Nov 25, 2009 at 5:35 PM, Edward Diener
No, it is not correct. A bimap is a mapping between two sets of
elements (named the left set, and the right set) that can be viewed as
a std map

Lex Wassenberg wrote:
Bimap automatically adds the map data to the left side of the bimap. If
any data can not be added, such as the (3,20), (4,20), it acts in
exactly the same fashion as it normally would when one tries to insert a
data pair which is not distinct both ways.
My point is that I wanted a constructor as above:
Boost::bimap

2009/11/25 Edward Diener
In my opinion the constructor you propose is not obvious, but rather very subtle. Explicit 'left' or 'right' during the conversion from std::map makes the intent more explicit and thus improves readability. I do understand that it might be a matter of personal preference. Roman Perepelitsa.
participants (4)
-
Edward Diener
-
Lex Wassenberg
-
Matias Capeletto
-
Roman Perepelitsa