簡體   English   中英

推進標准地圖的迭代器

[英]advance the iterator of a standard map

主要問題已經出現在標題中: 如何推進標准地圖的迭代器?

但是由於大多數人都會問為什么我需要這個,我會提供更多信息:我有一個有幾個地圖的課程。 我有至少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
    }

};

在我的程序過程中,我需要實例化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);
    }
}

因此,閱讀器中的功能應如下所示:

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);的意圖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;
}

還有其他可能性嗎? 提前謝謝了!

std::mapiterator_category雙向迭代器iterator_category 這意味着沒有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的step參數可以是負數,在這種情況下,它將調用--it在封面下。 如果要返回遞減的迭代器,可以使用std::prev

推進的原型是:

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

你需要提供一個變量來推進。 因此,以下內容將起作用:

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

但是,這內部只是像你想要避免的那樣循環。 循環是推進地圖迭代器的唯一方法。 如果使用向量或雙端隊列,則continer.begin() + index有效,因為它們具有Random Access iterators ,而映射則不然。

我認為你真正想要的是這個,它在你的地圖中找到index並返回一個迭代器:

auto it = maxwellSensors.find(index);

請參閱高級簽名和文檔: http//en.cppreference.com/w/cpp/iterator/advance

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

這意味着正確的用法是:

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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM