Take the 2-minute tour ×

This question might be a bit sketchy because I do not have the code available at home, but I know this thing otherwise will bug me the whole weekend.

When I tried to update some code to C++11 I began replacing some std::map with std::unordered_map. The code only used std::map::find() to access a specific element in the map, so I figured the replacement should be easy. The returned iterator was stored in an auto-typed variable (auto res = map.find( x ), so the typing should check out fine. However when accessing the stored element using res->second.do_stuff() I got a compiler error, telling me, that struct std::pair<char, B> does not have a member second. Now this really confused me, but unfortunately I did not have time to investigate further.

Maybe this is enough information, so someone can give me a hint on this weird compiler error. Or is my understanding that std::map and std::unordered_map should have the same interface except for the parts which need an ordering, not correct?


As promised here some more analysis on the problem. Most likely this will allow someone to help me out better now. As I guessed from the hints in the comments, this was not really caused by the point where I accessed the elements in the map, but by some other part of the code. The reason I found was, that I used the map within Class X to store pointers to other elements of Class X (a kind of tree structure). However this seems to work for std::map but not for std::unordered_map. Here is some very simple code that exhibits the problem:

#include <stdint.h>
#include <unordered_map>
#include <map>

class Test {
  std::map<uint32_t, Test> m_map1; // Works
  std::unordered_map<uint32_t, Test> m_map; // gives error: ‘std::pair<_T1, _T2>::second’ has incomplete type

int main() {
  return 1;

std::map works std::unordered_map does not work. Any Ideas why this is the case, or what can be done to get it to work with a std::unordered_map?

share|improve this question
The interface is roughly the same, but you'll need to make sure your key types are hashable rather than merely comparable. –  ildjarn Dec 9 '11 at 22:50
@ildjarn: The keys are simple char as given in the example, so they should be easily hashable. Also the problem does not appear in the definition of the std::unordered_map<char, B> map or at the point where I call find( x ) on it, but rather at the point where I try to access the iterator (or more precisely the member second). That is the part that got me confused. –  LiKao Dec 9 '11 at 22:53
Could you produce a minimal example that exhibits the problem? –  Karl Knechtel Dec 9 '11 at 23:04
what do you mean it doesn't work? std::unordered_map: ideone.com/P2XUa std::map: ideone.com/etuCH –  Gene Bushuyev Dec 9 '11 at 23:22
Your code compiles fine on my MSVC 2010. –  Werner Henze Dec 12 '11 at 12:48

2 Answers 2

up vote 11 down vote accepted

I guess that because std::unordered_map needs to rehash, and therefore copy elements, the types need to be complete, whereas a map, only ever working with pointers to elements, will not exhibit that problem.

The solution here is to have an unordered map to a pointer:

std::unordered_map<uint32_t, std::shared_ptr<Test> >. 
share|improve this answer
Yes, exactly. Unfortunately I did not have time yet, to write a more detailed explanation myself, so I'll let you have the credit ;-). Another thing to note at this point is, that both lines are invalid. As explained in drdobbs.com/184403814 incomplete types are never allowed by STL-Collections, so the code was invalid before, but the compiler never caught this. This probably is one of those cases, where undefined behavior doesn't hurt you usually, but you cannot be sure. At least now we are safe. –  LiKao Dec 13 '11 at 11:23

Using both map and unordered_map with incomplete types involves undefined-behavior:

In particular, the effects are undefined in the following cases:



share|improve this answer
Where is that quote from? –  Ralph Tandetzky Aug 7 '13 at 13:11
@RalphTandetzky: from the standard library requirements part of the C++ standard. I think it was there since C++98. –  ybungalobill Aug 9 '13 at 15:30
It could be nice if compilers could generate good error messages and not generate working code in this case (containers of incomplete type). We have no way to ensure that our code will work tomorrow on another compiler/version. –  Renaud Jan 8 at 9:05
@Renaud: This is a part of a more general discussion of whether undefined behavior is good or bad. Sometimes you do not care for porting your code to other platforms, but doing something exploiting the knowledge of your implementation is useful. E.g. the useful struct Tree { std::list<Tree> children; }; works correctly with my toolchain, but will fail if done as you say. Other example is casting pointers to non-PODs whose memory layout I know to be identical, but technically is undefined behavior. –  ybungalobill Jan 9 at 16:28

Your Answer


