我有此代码,该代码适用于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
和Foo
可以使用Bar
。
之所以能够工作,是因为GCC库实现恰恰不需要实例化地图的键类型来实例化迭代器。
这可以保证吗?在定义映射迭代器类型时,该标准似乎有些过时。该代码的移植性如何?
答案 0 :(得分:3)
这将导致不确定的行为。
在声明ActiveSheet.PivotTables("PivotTable1").PivotFields("MONTH").PivotItems("jan")
中,MyMap::iterator i;
必须是完整类型,因此它是隐式实例化的。但是,MyMap
和Foo
在实例化时还不完整,因此根据[res.on.functions]/2,行为是不确定的:
尤其是在以下情况下,效果是不确定的:
- ...
- 如果在实例化模板组件或评估概念时将不完整的类型([basic.types])用作模板参数,除非该组件特别允许。
答案 1 :(得分:0)
您可以通过考虑std::map
是基于节点的容器这一事实来回避整个问题,以便使其包含元素的节点具有稳定的地址。即您可以使用普通指针而不是迭代器(当然,只要不需要迭代器即可传递到std::map
的成员函数中):
class Foo
{
std::pair<Foo const, Bar>* some_data;
};
请注意,这里只需要Foo
,Bar
和std::pair<>
的声明即可定义成员some_data
。
如果您使用boost::multi_index
(在许多方面都优于std
关联容器),则它具有极其有用的功能to_iterator
,该函数可以引用元素并返回一个迭代器,它。