Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why can't I replace std::map with std::unordered_map

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?

EDIT:

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?

like image 824
LiKao Avatar asked Dec 09 '11 22:12

LiKao


1 Answers

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

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

[...]

— if an incomplete type (3.9) is used as a template argument when instantiating a template component, unless specifically allowed for that component.

like image 84
Yakov Galka Avatar answered Sep 28 '22 20:09

Yakov Galka