g++ unordered_map has no at() function?

*爱你&永不变心* 提交于 2019-12-12 16:13:57

问题


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.


回答1:


GCC 4.4 already supports these features as part of -std=c++0x. There is no need for the tr1 namespace, and the include can just be <unordered_map>.

Either way, don't be too liberal with using namespace, especially with namespaces that may have considerable overlap, this becomes a big problem. For more information about the use of namespaces, have a look at GOTW.




回答2:


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.



回答3:


For unordered_map, I've been using this documentation: cplusplus.com, which shows an at() method to look up a key in the map.

But you're not using unordered_map, you're using tr1::unordered_map. That's not the same thing.

The docs you're looking at are for part of the C++11 standard library, which was published in 2011. The GCC release you're using is from 2009. Unsurprisingly GCC 4.4 doesn't support C++11 properly. TR1 is not the same thing as C++11, the containers in TR1 are early experimental versions, and don't include the at() member.

In any case, cplusplus.com is rubbish, you're better off looking at http://cppreference.com

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

std::tr1::unordered_map doesn't have an at() member. You can enable experimental support for C++0x (the "codename" used before C++11 was finished) in GCC 4.4 with the -std=c++0x option, allowing you to use GCC's version of std::unordered_map, but requiring clients to do the same to use your code is not a great idea. Stick to portable features that are properly supported in your compiler version.

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

Follow a "Standard C++ Library Manual" link, then the "API and Source Documentation" link, then there's a link to the API reference for the 4.4 release

Don't forget to check the right docs, either std::tr1::unordered_map or std::unordered_map, depending which you're trying to use.




回答4:


Equivalent should be:

mymap->find(key)->second

find() gives you an iterator, so you should check that this is not mymap.end().



来源:https://stackoverflow.com/questions/19277122/g-unordered-map-has-no-at-function

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!