std::map<K,V>::iterator 是否实例化 std::map<K,V>?

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

我有这段代码,适用于 GCC:

#include <map>

class Foo;
class Bar;

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

MyMap::iterator i;

class Foo
{
    MyMap::iterator some_data;
};

当前设计的代码(这是令人不快的循环,是的,我坚持使用它)需要 map<Foo,Bar>::iterator 可用于 FooBar

之所以可行,是因为 GCC 库实现恰好不需要实例化映射的键类型来实例化迭代器。

这有保障吗?在定义地图迭代器类型时,该标准似乎有些放手。此代码的可移植性如何?

考虑到 std::map 是一个基于节点的容器这一事实,您可以回避整个问题,因此其包含元素的节点具有稳定的地址。 IE。你可以使用普通指针而不是迭代器(当然,只要你不需要迭代器传递给 std::map 的成员函数):

class Foo
{
    std::pair<Foo const, Bar>* some_data;
};

请注意,这里只需要 声明 FooBarstd::pair<> 来定义成员 some_data

如果您使用 boost::multi_index(它在许多方面优于 std 关联容器),那么它具有非常有用的函数 to_iterator,可以引用元素和 returns 它的一个迭代器。

这会导致未定义的行为。

在声明MyMap::iterator i;中,MyMap要求是一个完整的类型,因此被隐式实例化。但是,FooBar 在这个实例化点还没有完成,所以根据 [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.