33

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).

Alexis Wilke
  • 19,179
  • 10
  • 84
  • 156
rubenvb
  • 74,642
  • 33
  • 187
  • 332
  • 7
    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. – David Rodríguez - dribeas Apr 13 '11 at 10:29
  • 1
    @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. – rubenvb Apr 13 '11 at 11:07
  • 7
    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. – ildjarn Apr 13 '11 at 19:45

2 Answers2

32

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

Community
  • 1
  • 1
ildjarn
  • 62,044
  • 9
  • 127
  • 211
  • 26
    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). – OJFord Mar 19 '15 at 16:36
  • 3
    @OllieFord : It was a rather tongue-in-cheek joke, as 'no' was too short to post as its own answer. ;-] – ildjarn Mar 23 '15 at 01:00
  • 16
    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. – rubenvb Jan 23 '17 at 10:36
  • @rubenvb : 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. – ildjarn Jan 23 '17 at 10:39
  • 8
    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. – rubenvb Jan 23 '17 at 10:40
  • @rubenvb : 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. – ildjarn Jan 23 '17 at 10:42
  • 6
    Correct me if I am wrong, but isn't the primary use case for a `Bimap` 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. – CygnusX1 Jan 05 '19 at 11:04
  • 3
    @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. – Violet Giraffe Jan 18 '20 at 19:23
  • @VioletGiraffe : And yet, to date, 48 people disagree with you. /shrug – ildjarn Jan 19 '20 at 00:24
  • 3
    @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. – Violet Giraffe Jan 19 '20 at 16:42
  • @VioletGiraffe : It implies that _you_ missed the point, not them. Thanks for your input. – ildjarn Jan 19 '20 at 17:26
  • 2
    @ildjarn 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 sequence – TCSGrad Apr 27 '21 at 00:22
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.

Clinton
  • 22,361
  • 15
  • 67
  • 163