Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Does std::map<K,V>::iterator instantiate std::map<K,V>?

I have this code, which works on GCC:

#include <map>

class Foo;
class Bar;

typedef std::map<Foo,Bar> MyMap;

MyMap::iterator i;

class Foo
{
    MyMap::iterator some_data;
};

The code as currently designed (which is unpleasantly circular yes I'm stuck with it) requires map<Foo,Bar>::iterator to be available to Foo and Bar.

It works because the GCC library implementation happens to not need to instantiate the map's key type in order to instantiate the iterator.

Is this guaranteed? The standard seems to be somewhat hands-off when it comes to defining the map iterator type. How portable is this code?

like image 558
spraff Avatar asked Mar 08 '19 14:03

spraff


People also ask

Whats std::map?

std::map is a sorted associative container that contains key-value pairs with unique keys. Keys are sorted by using the comparison function Compare . Search, removal, and insertion operations have logarithmic complexity. Maps are usually implemented as red-black trees.

Is std::map ordered?

Yes, a std::map<K,V> is ordered based on the key, K , using std::less<K> to compare objects, by default.


1 Answers

This results in undefined behavior.

In the declaration MyMap::iterator i;, MyMap is required to be a complete type, thus it is implicitly instantiated. However, Foo and Bar are not complete at this point of instantiation, so the behavior is undefined according to [res.on.functions]/2:

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

  • ...
  • if an incomplete type ([basic.types]) is used as a template argument when instantiating a template component or evaluating a concept, unless specifically allowed for that component.
like image 155
xskxzr Avatar answered Oct 14 '22 01:10

xskxzr