Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

g++ unordered_map has no at() function?

I've been developing using Visual Studio 2010, and then compiling a Linux 64 version on another machine. To cover the difference between the 2 different compilers/environments, we have conditional include statements:

#ifdef __linux__
#include <tr1/unordered_map>
#endif

#ifdef _WIN32
#include <unordered_map>
#endif 
using namespace std;  // covers std::unordered_map
using namespace std::tr1; // covers tr/unordered_map

unordered_map<string,string> map;

For unordered_map, I've been using this documentation: cplusplus.com, which shows an at() method to look up a key in the map. (Unlike the [] operator, this won't insert key into the map if not found.)

When I tried to compile the code on the Linux machine, gcc throws an error saying

test_map.cpp:18: error: 'class std::tr1::unordered_map, std::allocator >, std::basic_string, std::allocator >, std::tr1::hash, std::allocator > >, std::equal_to, std::allocator > >, std::allocator, std::allocator >, std::basic_string, std::allocator > > >, false>' has no member named 'at'

The version of gcc on this machine is:

g++ (GCC) 4.1.2 20080704 (Red Hat 4.1.2-46)

I tried compiling on a newer install of Linux with version:

gcc version 4.4.6 20120305 (Red Hat 4.4.6-4) (GCC)

and got the same error.

So my question has 2 parts:

  • Is there a work around so I can still use the unordered_map.at() function?

  • Where would I find the API docs for Linux unordered_map so I can be aware of any other discrepancies? (I looked at GNU online docs but I could figure out where to find the API reference that shows class and functions.)

UPDATE

I learned a lot from the responses posted here, so thanks to all. us2012's answer explained how to work around the compile issue, but in the end, I switched to using boost::unordered_map as suggested by John Dibling. (I decided to take everyone's warnings about the experimental C++11 support seriously, as well as also not wanting to inadvertently force a compiler setting on clients who are using our library.) This gave me a clean compile in both Windows and Linux, and no code change was required (other than removing the reference to std and tr1). Also I switched to use http://cppreference.com site, which has straightened me out with other problems already as well. (Surprisingly, this site never came up in any of my Google searches for C++ API docs.)

Thanks again, for everyone's great explanations.

like image 200
Sam Goldberg Avatar asked Dec 16 '22 05:12

Sam Goldberg


1 Answers

You're in a pretty sticky spot.

GCC 4.4.6, which is what's in the RHEL6 distro, is pre-C++11. The TR1 libraries predate C++11, and many of the components that were introduced to C++11 were signifigantly changed from TR1 before Standardization was complete.

unordered_map is one of those components.

In the TR1 days, unordered_map didn't have an at() member function. This is present in the C++11 spec.

Your VS2010 compiler is using the C++11 spec (at least for unordered_map, to a degree), but GCC 4.4.6 has no concept of C++11. You are compiling against 2 different languages, in effect.

It's all still C++, at least at some level, so there should be an opportunity to find some common ground. For what it's worth, I don't think that I would personally use anything from TR1 for production work -- but that's me.

As suggested elsewhere, to achieve the same effect you can find the key.

The bottom line for you I think is this. In GCC 4.4, C++0x support (note I don't say C++11) is experimental. If it were me, I would not use any of the std=c++0x functionality for production work. I would also not use TR1 for production work.

This leaves you three choices:

  1. Don't use a hash map at all
  2. Use a hash map from Boost, or another reputable 3rd party library
  3. Write your own hash map.
like image 114
John Dibling Avatar answered Dec 29 '22 01:12

John Dibling