Storing Iterators of std::deque

二次信任 提交于 2019-12-11 14:16:41

问题


I am trying to store iterators of a deque in a vector and want to preserve them inside the vector even when I have erased or inserted some elements from or into the deque. Is this possible?

I have the following code:

typedef struct {

int id;
int seedId;
double similarity;

} NODE_SEED_SIM;

typedef std::deque<NODE_SEED_SIM> NodesQueue;
typedef std::deque<NODE_SEED_SIM>::iterator ITRTR;
typedef std::vector<const ITRTR> PointerVec;  

void growSegments (CSG_PointCloud *pResult, IntMatrix *WdIndices, NodesQueue *NodesList, IntMatrix *Segments) {

    ITRTR nodeslistStart = (*NodesList).begin();
    int pointCount = (*WdIndices).size();
    int nodeslistSize = (*NodesList).size();

    IntVector book(pointCount);
    PointerVec pointerList (pointCount); // Vector of ITRTRs

    for (int i = 0; i < nodeslistSize; i++) {

         book [ (*NodesList)[i].id ] = 1;
         pointerList [ (*NodesList)[i].id ] = nodeslistStart + i; // REF: 2

    }

    while (nodeslistSize > 0) {

    int i = 0;
    int returnCode = 0;
    int nodeId = (*NodesList)[i].id;
    int seedId = (*NodesList)[i].seedId;
    int n_nbrOfNode = (*WdIndices)[ nodeId ].size();

    (*Segments)[ seedId ].push_back ( nodeId );
    (*NodesList).erase ( (*NodesList).begin() ); // REF: 3; This erase DOES NOT mess the pointerList
    nodeslistSize --;

    Point node;
    /*
               GET ATTRIBUTES OF NODE
            */

    for (int j = 0; j < n_nbrOfNode; j++) {

        int nborId = (*WdIndices)[nodeId][j];

        if (nborId == seedId)
            continue;

        Point neighbor;
        /*
                        GET ATTRIBUTES OF NEIGHBOUR
                    */

        double node_nbor_sim = computeSimilarity (neighbor, node);

        if (book[nborId] == 1) {

            ITRTR curr_node = pointerList[nborId]; // REF: 1

            if ( curr_node -> similarity < node_nbor_sim) {

                curr_node -> similarity = node_nbor_sim;
                NODE_SEED_SIM temp = *curr_node;
                (*NodesList).erase (curr_node); // REF: 4; This erase completely messes up the pointerList
                returnCode = insertSortNodesList (&temp, NodesList, -1);


            }

        }

    }

}

}

The nodes in the NodesList hold a global ID inside them. However they are stored in NodesList, not according to this global ID but in descending order of their "similarity". So later when I want to get the node from NodesList corresponding to a global ID (nborID in code)[REF: 1] I do it via the "pointerList" where I have previously stored the iterators of the deque but according to the global IDs of the nodes [REF: 2]. My pointerList stays true after the first erase command [REF: 3], but gets messed up in the next erase [REF: 4].

What is wrong here? Thanks


回答1:


I am trying to store iterators of a deque in a vector and want to preserve them inside the vector even when I have erased or inserted some elements from or into the deque. Is this possible?

As from the documentation it says

Sorry I'm posting this as an image here, but the formatting is too tedious to replicate in markup!

So the short answer is: NO! I'm afraid you cannot safely store iterators pointing to certain elements stored in a std::deque, while it's changed elsewhere.

Some other relevant Q&A:

  • Problem with invalidation of STL iterators when calling erase
  • C++ deque: when iterators are invalidated



回答2:


If you want to create a vector of iterators then this is what you want to do:

#include<iostream>
#include <deque>
#include <vector>
using namespace std;
int main()
{
    deque<int> dq { 1, 2, 3, 4, 5, 6, 7, 8 };
    deque<int>::iterator it;

    vector<deque<int>::iterator> vit;
    for (it = dq.begin(); it != dq.end(); it++)
    {
        vit.push_back(it);
        cout << *it;
    }

    //note that `it` is a pointer so if you modify the `block` it points in your deque then the value will change.
    //If you delete it then you will have a segmenant fault.
    //--- Don't Do: while (!dq.empty()) { dq.pop_back(); } ---//

    for (size_t i = 0; i < vit.size(); i++)
    {
        cout << *vit[i];
    }

    system("pause");
    return 0;
}

However, if you want to preserve that value of that iterator after it has been changed/deleted you may want to create a copy of each iterator and store the copy rather than the actual iterator



来源:https://stackoverflow.com/questions/24210488/storing-iterators-of-stddeque

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!