Promote a standard map iterator

The main question is already in the title: How to configure a standard map iterator?

But since most people ask why I need this, I will provide additional information: I have a class that has several maps. I have at least 2 differential equations, at least 2 types of sensors (field or dft) and at least 2 types of space (volume, surface). I need to save all these things and make a correlation between them. So I thought it would be wise to have cards of these things, and when things correlate with each other, they have the same key on their cards.

For simplicity, we consider only three mappings.

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
    }

};

SensorInterface. , maxwell, maxwell .

:

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);
    }
}

, :

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;
    }
}

... 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)

, ?

auto maxIt = maxwellSensors.begin() + index;, .

: for, :

auto maxIt = maxwellSensors.begin();
for(uint i = 0; i < index; ++i){
    ++maxIt;
}

? !

+3
4

iterator_category std::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 

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

, std::advance void . , std::next

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

std::advance , --it . , std::prev.

+7

:

template <class InputIterator, class Distance>
  void advance (InputIterator& it, Distance n);

, :

auto maxIt = maxwellSensors.begin();
std::advance(maxIt, index);

auto maxIt = std::advance(maxwellSensors.begin(), index); // Failed
+3

. , :

auto it = maxwellSensors.begin();
std::advance(it, index);

However, this internally just makes a loop as you wanted to avoid. A loop is the only way to advance a map iterator. If you use a vector or deque, then it continer.begin() + indexis valid, since they have Random Access iterators, but the map does not.

I think what you really want is what it finds indexon your map and returns an iterator to it:

auto it = maxwellSensors.find(index);
+2
source

See pre-signing and documentation: http://en.cppreference.com/w/cpp/iterator/advance

template< class InputIt, class Distance >
void advance( InputIt& it, Distance n );

This means that proper use:

auto maxIt = maxwellSensors.begin();
std::advance( maxIt , index);
+1
source

All Articles