Is there a Boost.Bimap alternative in c++11?
Asked Answered
H

2

34

Is there a usable alternative to Boost's bimap in C++0x?

I would like to avoid Boost, but fully embrace C++11. If necessary, a slimmed down version of Boost's bimap would work for me (I need a constant bimap to switch between enums and corresponding strings) throughout my program. The map will be compile-time constant, so perhaps even two manually maintained maps aren't the optimal solution.


UPDATE: I found this on The Code Project, but it seems licensing may be an issue: http://www.codeproject.com/KB/stl/bimap.aspx?fid=12042&df=90&mpp=25&noise=3&sort=Position&view=Quick&fr=151#xx0xx

I'm just looking for a clean and easy solution (one header/source file or little extra, as two mirrorred maps are equally fine in my case).

Herald answered 13/4, 2011 at 9:52 Comment(3)
Why do you want to avoid using boost? If it solves your problem... Note that boost contains many different libraries, some of which made it into the standard, but many of which are too specific to be added to the standard.Superjacent
@David: I understand, but 1) Boost on Windows is a hassle, 2) I want to learn C++ with this project; I know Boost is C++ and a good way to learn it, but I'd like to see what I can do myself and discover the already present functionality. Weird explanation I know, but everything in Boost (I would need) needs non-header-only stuff, which is big, at least. And I've been able to avoid/work around Boost quite simply for now, I'd like to keep it that way. I have reduced the problem to a container wrapper which essentially keeps two maps updated, which isn't really a hard thing to do yourself.Herald
How is boost on Windows a hassle, especially when talking about a header-only library such as boost.bimap? Extract the headers, add them to your include directories, done.Subaltern
L
15

My feeling is a lot of the work that goes into Boost libraries is making them work with other libraries/STL.

If you don't need that capability, you could just use a class with a std::map<X*, Y*> and std::map<Y*, X*>. Then have methods like the following: add(X,Y), remove(X,Y), get_left(X) and get_right(Y).

If you want to store copies, add(X,Y) could allocate memory, and remove(X,Y) can de-allocate. Also, you can then define a destructor that calls remove(X,Y) on the remainder of the elements.

Lettie answered 14/4, 2011 at 1:4 Comment(2)
Shouldn't this be std:map<Y, X*> and std::map<X, Y*>Humpbacked
"you don't need it, you just need to implement it"Victoir
S
33

Short answer: no.

Long answer: nope.


It should be noted that C++14's support for transparent comparators eliminates the need for Boost.Bimap 90% of the time*: when you need to key off of any given property of an object (stored or computed), often a simple, bitwise-comparable unique identifier inherent to/present in the object anyway. With transparent comparators, you can compare an object to any possible value, discriminated only by type, as long as said value can be obtained/computed from an object without mutating it.

* a guesstimate, not a statistic

Subaltern answered 13/4, 2011 at 9:56 Comment(12)
I don't know why this is so upvoted - I think a better "long answer" would be a brief explanation of why it isn't deemed necessary; what would be a more idiomatic approach. I think a lot of people (I'm certainly guilty) stumble across Boost when they're trying to hack something together in a not very C++-y way; OP's desire to avoid it to learn is good I think (not least because I share it).Duad
@OllieFord : It was a rather tongue-in-cheek joke, as 'no' was too short to post as its own answer. ;-]Subaltern
So how would transparent comparators help in defining an enum<->string bimap? This would make this answer actually answer my question. Currently, it reads like a shallow advertisement for a C++14 feature without any indication of usefulness.Herald
@Herald : It doesn't help with enum<->string, but I'd wager it helps the majority of people who need a Bimap. I tried to make that quite clear in the answer.Subaltern
Then this answer is not an answer to this question, even though I could agree with your sentiment if I knew how it applied to this situation.Herald
@Herald : It is an answer to "Is there a Boost.Bimap alternative in c++11?", and offers an alternative for people who are asking that same question. 40 other people apparently agree. If your real question is about enum<->string and not about Bimap then you have an XY problem and hence a poorly-asked question. Downvote all you want.Subaltern
Correct me if I am wrong, but isn't the primary use case for a Bimap<T,U> to be able to perform efficient searches with respect to T and U (By efficient I mean log n complexity)? That involves using two indexing structures for elements of T and U. Using transparent comparators do not achieve that.Bilharziasis
@CygnusX1: that's what I came here for, too. This answer is off-topic and doesn't do a good job explaining the idea behind it at all.Anemography
@VioletGiraffe : And yet, to date, 48 people disagree with you. /shrugSubaltern
@ildjarn: And I bet they missed the point you were trying to make as well. This is a low-quality answer if I ever seen one.Anemography
@VioletGiraffe : It implies that you missed the point, not them. Thanks for your input.Subaltern
@Subaltern How do you propose to use the said "transparent comparators" feature to have efficient searchable index with insertion order maintained ? Say a container storing unique integers while also keeping track of the insertion sequenceNessus
L
15

My feeling is a lot of the work that goes into Boost libraries is making them work with other libraries/STL.

If you don't need that capability, you could just use a class with a std::map<X*, Y*> and std::map<Y*, X*>. Then have methods like the following: add(X,Y), remove(X,Y), get_left(X) and get_right(Y).

If you want to store copies, add(X,Y) could allocate memory, and remove(X,Y) can de-allocate. Also, you can then define a destructor that calls remove(X,Y) on the remainder of the elements.

Lettie answered 14/4, 2011 at 1:4 Comment(2)
Shouldn't this be std:map<Y, X*> and std::map<X, Y*>Humpbacked
"you don't need it, you just need to implement it"Victoir

© 2022 - 2024 — McMap. All rights reserved.