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?
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.
Yes, a std::map<K,V> is ordered based on the key, K , using std::less<K> to compare objects, by default.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With