std :: map <k,v> :: iterator会实例化std :: map <k,v>吗?

时间:2019-03-08 14:19:30

标签: c++ templates iterator stdmap c++-standard-library

我有此代码,该代码适用于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>::iteratorFoo可以使用Bar

之所以能够工作,是因为GCC库实现恰恰不需要实例化地图的键类型来实例化迭代器。

这可以保证吗?在定义映射迭代器类型时,该标准似乎有些过时。该代码的移植性如何?

2 个答案:

答案 0 :(得分:3)

这将导致不确定的行为。

在声明ActiveSheet.PivotTables("PivotTable1").PivotFields("MONTH").PivotItems("jan") 中,MyMap::iterator i;必须是完整类型,因此它是隐式实例化的。但是,MyMapFoo在实例化时还不完整,因此根据[res.on.functions]/2,行为是不确定的:

  

尤其是在以下情况下,效果是不确定的:

     
      
  • ...
  •   
  • 如果在实例化模板组件或评估概念时将不完整的类型([basic.types])用作模板参数,除非该组件特别允许。
  •   

答案 1 :(得分:0)

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

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

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

如果您使用boost::multi_index(在许多方面都优于std关联容器),则它具有极其有用的功能to_iterator,该函数可以引用元素并返回一个迭代器,它。