推进标准地图的迭代器

Ric*_*o-E 3 c++ iterator stdmap bidirectional stdadvance

主要问题已经出现在标题中:如何推进标准地图的迭代器?

但是由于大多数人都会问为什么我需要这个,我会提供更多信息:我有一个有几个地图的课程.我有至少2个微分方程,至少2种传感器类型(场或dft)和至少2种空间类型(体积,表面).我需要保存所有这些东西,并在它们之间建立关联.因此我认为拥有这些东西的地图是明智的,当事物彼此相关时,它们在地图中具有相同的关键字.

为简单起见,我们只考虑三张地图.

class Reader
{
    struct MaxwellSensor
    {
        // some members...
    };
    struct FieldSensor
    {
        // some members
        uint fieldMember;
    };
    struct DFTSensor
    {
        // some members
        uint dftMember;
    };    
    std::map<uint, MaxwellSensor> maxwellSensors;
    std::map<uint, FieldSensor> fieldSensors;
    std::map<uint, DFTSensor> dftSensors;

    uint getCountOfMaxwellSensors(){
        return maxwellSensors.size();
    }

    uint getMemberForMaxwellSensorByIndex(uint index){
        // This follows later
    }

};
Run Code Online (Sandbox Code Playgroud)

在我的程序过程中,我需要实例化a的几个变量SensorInterface.为此,我需要知道我有多少个麦克斯韦传感器,然后迭代通过麦克斯韦传感器并获得其他传感器的成员.

这看起来像:

class MyType{
    public:
        uint member;
}

int main(int argc, const char* argv[])
{
    // some code
    Reader myReader;
    for(uint i = 0; i < myReader.countOfMaxwellSensors(); ++i)
    {
        MyType var;
        var.member = myReader.getMemberForMaxwellSensorByIndex(i);
    }
}
Run Code Online (Sandbox Code Playgroud)

因此,阅读器中的功能应如下所示:

uint getMemberForMaxwellSensorByIndex(uint index)
{
    auto maxIt = std::advance(maxwellSensors.begin(), index);
    auto foundInFieldSensorsIt = std::find_if(fieldSensors.begin(), fieldSensors.end(), [&] (const std::pair<UInteger_T, FieldSensor>& kvp) { return kvp.first == maxIt->first; });
    auto foundInDFTSensorsIt = std::find_if(dftSensors.begin(), dftSensors.end(), [&] (const std::pair<UInteger_T, DFTSensor>& kvp) { return kvp.first == maxIt->first; });
    if(foundInFieldSensorsIt != fieldSensors.end())
        return fieldSensors[maxIt->first].fieldMember;
    else if(foundInDFTSensorsIt != dftSensors.end())
        return dftSensors[maxIt->first].fieldMember;
    else
    {
        std::cerr << "something went wrong." << std::endl;
        return 0;
    }
}
Run Code Online (Sandbox Code Playgroud)

所以...这是意图std::advance(maxwellSensors.begin(), index);但是这不能用这个错误代码编译:

error: 
  no matching function for call to 'advance'
        auto maxIt = std::advance(maxwellSensors.begin(), index);
                     ^~~~~~~~~~~~
/c++/4.6/bits/stl_iterator_base_funcs.h:171:5: note: 
  candidate function [with _InputIterator = std::_Rb_tree_iterator<std::pair<const
  unsigned int, Reader<double, unsigned int>::MaxwellSensor> >,
  _Distance = unsigned int] not viable: expects an l-value for 1st argument
advance(_InputIterator& __i, _Distance __n)
Run Code Online (Sandbox Code Playgroud)

那么如何推进标准地图的迭代器呢?

我也试过auto maxIt = maxwellSensors.begin() + index;但没有运气.

而且:我想避免使用for循环:

auto maxIt = maxwellSensors.begin();
for(uint i = 0; i < index; ++i){
    ++maxIt;
}
Run Code Online (Sandbox Code Playgroud)

还有其他可能性吗?提前谢谢了!

Tem*_*Rex 9

iterator_categorystd::map是一个的双向迭代器.这意味着没有O(1)多步增量,例如您对随机访问迭代器的增量.对于后者,您可以写:

auto it = my_vector.begin(); // std::vector has random access iterators
std::advance(it, 4);         // NOT a loop, will call it += 4;
it += 4;                     // shorthand, not recommended in generic code 
Run Code Online (Sandbox Code Playgroud)

对于前者,你有

auto it = my_map.begin();    // std::map has bidirectional iterators
std::advance(it, 4);         // for (auto i = 0; i < 4; ++i) ++it;
Run Code Online (Sandbox Code Playgroud)

请注意,std::advancevoid返回类型.如果要返回高级迭代器,可以使用std::next

auto it = my_map.begin();
auto it4 = std::next(it, 4); // copies it, then advances and returns that copy
Run Code Online (Sandbox Code Playgroud)

步骤参数std::advance可以是负数,在这种情况下,它将--it在封面下调用.如果要返回递减的迭代器,可以使用std::prev.