title: C++: huge errors using clang to compile a map with iterators as values
body: <p>I'm trying to use iterators as values in a <code>std::map</code> so that I can efficiently lookup an object by either its <code>id</code> or iterate it efficiently by its <code>depth</code>.</p>
  
  <p>Consider the following code:</p>
  
  <pre><code>#include &lt;string&gt;
  #include &lt;algorithm&gt;
  #include &lt;array&gt;
  #include &lt;iostream&gt;
  #include &lt;random&gt;
  #include &lt;map&gt;
  #include &lt;unordered_map&gt;
  
  struct object {
      static int next_id;
      int id;
      int depth;
      std::map&lt;int, object&gt;::iterator id_it;
      std::multimap&lt;int, std::map&lt;int, object&gt;::iterator&gt;::iterator depth_it;
      static std::map&lt;int, object&gt; by_id;
      static std::multimap&lt;int, std::map&lt;int, object&gt;::iterator&gt; by_depth;
      object() = delete;
      object(object const &amp;) = delete;
      object(object &amp;&amp;) = delete;
      object &amp; operator=(object const &amp;) = delete;
      object &amp;&amp; operator=(object &amp;&amp;) = delete;
      ~object() = default;
      object(int id) : id(id), depth(rand()) {}
      void init(std::map&lt;int, object&gt;::iterator it) {
          id_it = it;
          depth_it = by_depth.emplace(depth, id_it);
      }
      static int create() {
          auto it = by_id.emplace(next_id, next_id).first;
          it-&gt;second.init(it);
          ++next_id;
          return it-&gt;second.id;
      }
      static void set_depth(int o, int d) {
          auto it = by_id.find(o);
          if (it == by_id.end())
              return;
          auto &amp; obj = it-&gt;second;
          obj.depth = d;
          by_depth.erase(obj.depth_it);
          obj.depth_it = by_depth.emplace(obj.depth, obj.id_it);
      }
      static int get_depth(int o) {
          auto it = by_id.find(o);
          if (it == by_id.end())
              return 0;
          return it-&gt;second.depth;
      }
      static int get_id(int o) {
          auto it = by_id.find(o);
          if (it == by_id.end())
              return 0;
          return it-&gt;second.id;
      }
      static void destroy(int o) {
          auto it = by_id.find(o);
          if (it == by_id.end())
              return;
          by_depth.erase(it-&gt;second.depth_it);
          by_id.erase(it-&gt;first);
      }
      template &lt;typename T&gt;
      static void with(T f) {
          for (auto it : by_depth) {
              f(it.second-&gt;second.id);
          }
      }
  };
  int object::next_id = 10000;
  std::map&lt;int, object&gt; object::by_id;
  std::multimap&lt;int, std::map&lt;int, object&gt;::iterator&gt; object::by_depth;
  
  
  int main() {
      for (int i = 0; i &lt; 100; ++i) {
          object::create();
      }
      for (int i = 0; i &lt; 100; ++i) {
          object::set_depth(rand() % 100 + 10000, rand());
      }
      object::with([](int obj) {
          std::cout &lt;&lt; object::get_id(obj) &lt;&lt; "-&gt;" &lt;&lt; object::get_depth(obj) &lt;&lt; std::endl;
      });
      for (int i = 0; i &lt; 100; ++i) {
          object::destroy(10000 + i);
      }
      object::with([](int obj) {
          std::cout &lt;&lt; "Object was not deleted!" &lt;&lt; std::endl;
      });
  }
  </code></pre>
  
  <p>Clang gives off <em>huge</em> errors, but MSVC compiles it fine <strong>in STRICT mode</strong>.</p>
  
  <p>Errors here:</p>
  
  <pre><code>In file included from error.cpp:1:
  In file included from /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../lib/c++/v1/string:434:
  In file included from /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../lib/c++/v1/algorithm:593:
  /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../lib/c++/v1/utility:221:9: error: 
        field has incomplete type 'object'
      _T2 second;
          ^
  /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../lib/c++/v1/__tree:602:16: note: 
        in instantiation of template class 'std::__1::pair&lt;int, object&gt;' requested here
      value_type __value_;
                 ^
  /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../lib/c++/v1/__tree:624:22: note: 
        in instantiation of template class 'std::__1::__tree_node&lt;std::__1::pair&lt;int, object&gt;,
        void *&gt;' requested here
      typedef typename __node::base                                 __node_base;
                       ^
  /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../lib/c++/v1/map:541:19: note: 
        in instantiation of template class 'std::__1::__tree_iterator&lt;std::__1::pair&lt;int, object&gt;,
        std::__1::__tree_node&lt;std::__1::pair&lt;int, object&gt;, void *&gt; *, long&gt;' requested here
      _TreeIterator __i_;
                    ^
  error.cpp:13:37: note: in instantiation of template class
        'std::__1::__map_iterator&lt;std::__1::__tree_iterator&lt;std::__1::pair&lt;int, object&gt;,
        std::__1::__tree_node&lt;std::__1::pair&lt;int, object&gt;, void *&gt; *, long&gt; &gt;' requested here
      std::map&lt;int, object&gt;::iterator id_it;
                                      ^
  error.cpp:9:8: note: definition of 'object' is not complete until the closing '}'
  struct object {
         ^
  In file included from error.cpp:6:
  /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../lib/c++/v1/map:834:44: error: 
        no viable conversion from 'iterator' (aka '__tree_iterator&lt;value_type, __node_pointer,
        difference_type&gt;') to 'iterator' (aka '__map_iterator&lt;typename __base::iterator&gt;')
            iterator end() _NOEXCEPT {return __tree_.end();}
                                             ^~~~~~~~~~~~~
  error.cpp:36:25: note: in instantiation of member function 'std::__1::map&lt;int, object,
        std::__1::less&lt;int&gt;, std::__1::allocator&lt;std::__1::pair&lt;const int, object&gt; &gt; &gt;::end'
        requested here
          if (it == by_id.end())
                          ^
  /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../lib/c++/v1/map:539:24: note: 
        candidate constructor (the implicit copy constructor) not viable: no known conversion from
        'iterator' (aka '__tree_iterator&lt;value_type, __node_pointer, difference_type&gt;') to 'const
        std::__1::__map_iterator&lt;std::__1::__tree_iterator&lt;std::__1::pair&lt;int, object&gt;,
        std::__1::__tree_node&lt;std::__1::pair&lt;int, object&gt;, void *&gt; *, long&gt; &gt; &amp;' for 1st argument
  class _LIBCPP_TYPE_VIS __map_iterator
                         ^
  /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../lib/c++/v1/map:539:24: note: 
        candidate constructor (the implicit move constructor) not viable: no known conversion from
        'iterator' (aka '__tree_iterator&lt;value_type, __node_pointer, difference_type&gt;') to
        'std::__1::__map_iterator&lt;std::__1::__tree_iterator&lt;std::__1::pair&lt;int, object&gt;,
        std::__1::__tree_node&lt;std::__1::pair&lt;int, object&gt;, void *&gt; *, long&gt; &gt; &amp;&amp;' for 1st argument
  class _LIBCPP_TYPE_VIS __map_iterator
                         ^
  In file included from error.cpp:6:
  In file included from /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../lib/c++/v1/map:371:
  /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../lib/c++/v1/__tree:1968:19: error: 
        static_cast from '__node_pointer' (aka 'std::__1::__tree_node&lt;std::__1::pair&lt;int, object&gt;,
        void *&gt; *') to '__node_base_pointer' (aka 'std::__1::__tree_node_base&lt;void *&gt; *') is not
        allowed
                    static_cast&lt;__node_base_pointer&gt;(__np));
                    ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../lib/c++/v1/__tree:1990:5: note: 
        in instantiation of member function 'std::__1::__tree&lt;std::__1::pair&lt;int, object&gt;,
        std::__1::__map_value_compare&lt;int, object, std::__1::less&lt;int&gt;, true&gt;,
        std::__1::allocator&lt;std::__1::pair&lt;int, object&gt; &gt; &gt;::erase' requested here
      erase(__i);
      ^
  /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../lib/c++/v1/map:937:25: note: 
        in instantiation of function template specialization 'std::__1::__tree&lt;std::__1::pair&lt;int,
        object&gt;, std::__1::__map_value_compare&lt;int, object, std::__1::less&lt;int&gt;, true&gt;,
        std::__1::allocator&lt;std::__1::pair&lt;int, object&gt; &gt; &gt;::__erase_unique&lt;int&gt;' requested here
          {return __tree_.__erase_unique(__k);}
                          ^
  error.cpp:60:15: note: in instantiation of member function 'std::__1::map&lt;int, object,
        std::__1::less&lt;int&gt;, std::__1::allocator&lt;std::__1::pair&lt;const int, object&gt; &gt; &gt;::erase'
        requested here
          by_id.erase(it-&gt;first);
                ^
  In file included from error.cpp:6:
  In file included from /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../lib/c++/v1/map:371:
  /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../lib/c++/v1/__tree:650:59: error: 
        static_cast from '__node_pointer' (aka 'std::__1::__tree_node&lt;std::__1::pair&lt;int, object&gt;,
        void *&gt; *') to '__node_base_pointer' (aka 'int') is not allowed
    ...= static_cast&lt;__node_pointer&gt;(__tree_next(static_cast&lt;__node_base_pointer&gt;(__ptr_)));
                                                 ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../lib/c++/v1/__tree:1961:5: note: 
        in instantiation of member function 'std::__1::__tree_iterator&lt;std::__1::pair&lt;int,
        object&gt;, std::__1::__tree_node&lt;std::__1::pair&lt;int, object&gt;, void *&gt; *, long&gt;::operator++'
        requested here
      ++__r;
      ^
  /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../lib/c++/v1/__tree:1990:5: note: 
        in instantiation of member function 'std::__1::__tree&lt;std::__1::pair&lt;int, object&gt;,
        std::__1::__map_value_compare&lt;int, object, std::__1::less&lt;int&gt;, true&gt;,
        std::__1::allocator&lt;std::__1::pair&lt;int, object&gt; &gt; &gt;::erase' requested here
      erase(__i);
      ^
  /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../lib/c++/v1/map:937:25: note: 
        in instantiation of function template specialization 'std::__1::__tree&lt;std::__1::pair&lt;int,
        object&gt;, std::__1::__map_value_compare&lt;int, object, std::__1::less&lt;int&gt;, true&gt;,
        std::__1::allocator&lt;std::__1::pair&lt;int, object&gt; &gt; &gt;::__erase_unique&lt;int&gt;' requested here
          {return __tree_.__erase_unique(__k);}
                          ^
  error.cpp:60:15: note: in instantiation of member function 'std::__1::map&lt;int, object,
        std::__1::less&lt;int&gt;, std::__1::allocator&lt;std::__1::pair&lt;const int, object&gt; &gt; &gt;::erase'
        requested here
          by_id.erase(it-&gt;first);
                ^
  In file included from error.cpp:6:
  In file included from /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../lib/c++/v1/map:371:
  /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../lib/c++/v1/__tree:650:19: error: 
        cannot cast from type 'int' to pointer type '__node_pointer' (aka
        'std::__1::__tree_node&lt;std::__1::pair&lt;int, object&gt;, void *&gt; *')
    ...= static_cast&lt;__node_pointer&gt;(__tree_next(static_cast&lt;__node_base_pointer&gt;(__ptr_)));
         ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../lib/c++/v1/__tree:156:14: error: 
        member reference type 'int' is not a pointer
      if (__x-&gt;__right_ != nullptr)
          ~~~  ^
  /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../lib/c++/v1/__tree:650:47: note: 
        in instantiation of function template specialization 'std::__1::__tree_next&lt;int&gt;'
        requested here
          {__ptr_ = static_cast&lt;__node_pointer&gt;(__tree_next(static_cast&lt;__node_base_pointe...
                                                ^
  /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../lib/c++/v1/__tree:1961:5: note: 
        in instantiation of member function 'std::__1::__tree_iterator&lt;std::__1::pair&lt;int,
        object&gt;, std::__1::__tree_node&lt;std::__1::pair&lt;int, object&gt;, void *&gt; *, long&gt;::operator++'
        requested here
      ++__r;
      ^
  /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../lib/c++/v1/__tree:1990:5: note: 
        in instantiation of member function 'std::__1::__tree&lt;std::__1::pair&lt;int, object&gt;,
        std::__1::__map_value_compare&lt;int, object, std::__1::less&lt;int&gt;, true&gt;,
        std::__1::allocator&lt;std::__1::pair&lt;int, object&gt; &gt; &gt;::erase' requested here
      erase(__i);
      ^
  /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../lib/c++/v1/map:937:25: note: 
        in instantiation of function template specialization 'std::__1::__tree&lt;std::__1::pair&lt;int,
        object&gt;, std::__1::__map_value_compare&lt;int, object, std::__1::less&lt;int&gt;, true&gt;,
        std::__1::allocator&lt;std::__1::pair&lt;int, object&gt; &gt; &gt;::__erase_unique&lt;int&gt;' requested here
          {return __tree_.__erase_unique(__k);}
                          ^
  error.cpp:60:15: note: in instantiation of member function 'std::__1::map&lt;int, object,
        std::__1::less&lt;int&gt;, std::__1::allocator&lt;std::__1::pair&lt;const int, object&gt; &gt; &gt;::erase'
        requested here
          by_id.erase(it-&gt;first);
                ^
  In file included from error.cpp:6:
  In file included from /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../lib/c++/v1/map:371:
  /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../lib/c++/v1/__tree:159:20: error: 
        member reference type 'int' is not a pointer
          __x = __x-&gt;__parent_;
                ~~~  ^
  /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../lib/c++/v1/__tree:160:17: error: 
        member reference type 'int' is not a pointer
      return __x-&gt;__parent_;
             ~~~  ^
  /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../lib/c++/v1/__tree:67:24: error: 
        member reference type 'int' is not a pointer
      return __x == __x-&gt;__parent_-&gt;__left_;
                    ~~~  ^
  /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../lib/c++/v1/__tree:158:13: note: 
        in instantiation of function template specialization 'std::__1::__tree_is_left_child&lt;int&gt;'
        requested here
      while (!__tree_is_left_child(__x))
              ^
  /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../lib/c++/v1/__tree:650:47: note: 
        in instantiation of function template specialization 'std::__1::__tree_next&lt;int&gt;'
        requested here
          {__ptr_ = static_cast&lt;__node_pointer&gt;(__tree_next(static_cast&lt;__node_base_pointe...
                                                ^
  /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../lib/c++/v1/__tree:1961:5: note: 
        in instantiation of member function 'std::__1::__tree_iterator&lt;std::__1::pair&lt;int,
        object&gt;, std::__1::__tree_node&lt;std::__1::pair&lt;int, object&gt;, void *&gt; *, long&gt;::operator++'
        requested here
      ++__r;
      ^
  /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../lib/c++/v1/__tree:1990:5: note: 
        in instantiation of member function 'std::__1::__tree&lt;std::__1::pair&lt;int, object&gt;,
        std::__1::__map_value_compare&lt;int, object, std::__1::less&lt;int&gt;, true&gt;,
        std::__1::allocator&lt;std::__1::pair&lt;int, object&gt; &gt; &gt;::erase' requested here
      erase(__i);
      ^
  /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../lib/c++/v1/map:937:25: note: 
        in instantiation of function template specialization 'std::__1::__tree&lt;std::__1::pair&lt;int,
        object&gt;, std::__1::__map_value_compare&lt;int, object, std::__1::less&lt;int&gt;, true&gt;,
        std::__1::allocator&lt;std::__1::pair&lt;int, object&gt; &gt; &gt;::__erase_unique&lt;int&gt;' requested here
          {return __tree_.__erase_unique(__k);}
                          ^
  error.cpp:60:15: note: in instantiation of member function 'std::__1::map&lt;int, object,
        std::__1::less&lt;int&gt;, std::__1::allocator&lt;std::__1::pair&lt;const int, object&gt; &gt; &gt;::erase'
        requested here
          by_id.erase(it-&gt;first);
                ^
  In file included from error.cpp:6:
  /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../lib/c++/v1/map:1586:44: error: 
        no viable conversion from 'iterator' (aka '__tree_iterator&lt;value_type, __node_pointer,
        difference_type&gt;') to 'iterator' (aka '__map_iterator&lt;typename __base::iterator&gt;')
            iterator end() _NOEXCEPT {return __tree_.end();}
                                             ^~~~~~~~~~~~~
  error.cpp:64:22: note: in instantiation of member function 'std::__1::multimap&lt;int,
        std::__1::__map_iterator&lt;std::__1::__tree_iterator&lt;std::__1::pair&lt;int, object&gt;,
        std::__1::__tree_node&lt;std::__1::pair&lt;int, object&gt;, void *&gt; *, long&gt; &gt;,
        std::__1::less&lt;int&gt;, std::__1::allocator&lt;std::__1::pair&lt;const int,
        std::__1::__map_iterator&lt;std::__1::__tree_iterator&lt;std::__1::pair&lt;int, object&gt;,
        std::__1::__tree_node&lt;std::__1::pair&lt;int, object&gt;, void *&gt; *, long&gt; &gt; &gt; &gt; &gt;::end'
        requested here
          for (auto it : by_depth) {
                       ^
  error.cpp:81:5: note: in instantiation of function template specialization 'object::with&lt;&lt;lambda
        at error.cpp:81:18&gt; &gt;' requested here
      object::with([](int obj) {
      ^
  /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../lib/c++/v1/map:539:24: note: 
        candidate constructor (the implicit copy constructor) not viable: no known conversion from
        'iterator' (aka '__tree_iterator&lt;value_type, __node_pointer, difference_type&gt;') to 'const
        std::__1::__map_iterator&lt;std::__1::__tree_iterator&lt;std::__1::pair&lt;int,
        std::__1::__map_iterator&lt;std::__1::__tree_iterator&lt;std::__1::pair&lt;int, object&gt;,
        std::__1::__tree_node&lt;std::__1::pair&lt;int, object&gt;, void *&gt; *, long&gt; &gt; &gt;,
        std::__1::__tree_node&lt;std::__1::pair&lt;int,
        std::__1::__map_iterator&lt;std::__1::__tree_iterator&lt;std::__1::pair&lt;int, object&gt;,
        std::__1::__tree_node&lt;std::__1::pair&lt;int, object&gt;, void *&gt; *, long&gt; &gt; &gt;, void *&gt; *, long&gt;
        &gt; &amp;' for 1st argument
  class _LIBCPP_TYPE_VIS __map_iterator
                         ^
  /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../lib/c++/v1/map:539:24: note: 
        candidate constructor (the implicit move constructor) not viable: no known conversion from
        'iterator' (aka '__tree_iterator&lt;value_type, __node_pointer, difference_type&gt;') to
        'std::__1::__map_iterator&lt;std::__1::__tree_iterator&lt;std::__1::pair&lt;int,
        std::__1::__map_iterator&lt;std::__1::__tree_iterator&lt;std::__1::pair&lt;int, object&gt;,
        std::__1::__tree_node&lt;std::__1::pair&lt;int, object&gt;, void *&gt; *, long&gt; &gt; &gt;,
        std::__1::__tree_node&lt;std::__1::pair&lt;int,
        std::__1::__map_iterator&lt;std::__1::__tree_iterator&lt;std::__1::pair&lt;int, object&gt;,
        std::__1::__tree_node&lt;std::__1::pair&lt;int, object&gt;, void *&gt; *, long&gt; &gt; &gt;, void *&gt; *, long&gt;
        &gt; &amp;&amp;' for 1st argument
  class _LIBCPP_TYPE_VIS __map_iterator
                         ^
  10 errors generated.
  </code></pre>
  
  <p>Invocation: <code>g++ -std=c++11 file.cpp</code> where g++ is clang.</p>
  
  <p>What's going on?</p>