C++ compare vector iterator with instance

时间:2022-05-15 04:20:10

I need to write a function that removes the received element from a vector. I think the way to do this is to parse the vector and compare the iterator with the reference passed. The problem is that I cannot compare the type iterator with type object reference...

我需要编写一个从向量中删除接收到的元素的函数。我认为这样做的方法是解析向量并将迭代器与传递的引用进行比较。问题是我无法将类型迭代器与类型对象引用进行比较...

BELOW THE ACTUAL CODE (Edit: originally I posted a much simplified version)

低于实际代码(编辑:最初我发布了一个简化版本)

struct BufferPoint{int x; int y; float pressure; };

class QueueState
{
public:
        VectorCurve *curveVector;
        RasterCurve *curveRaster;
        vector<BufferPoint> *curveBuffer;
        QueueState(vector<BufferPoint> *_b, VectorCurve *_v, RasterCurve *_r){ curveBuffer= _b; curveVector = _v; curveRaster = _r;};
};


vector<vector<BufferPoint>> queueBuffers;
vector<QueueState> queueStates;


[...]


// FIND AND REMOVE A BUFFER OBJECT
for(std::vector<QueueState>::iterator it = queueStates.begin(); it != queueStates.end(); ++it) 
{   

    //Remove buffer from pool (queue)
    //////////////////////////////////////////////////////////////////////////
    if((it->curveVector->state == CURVEDATA_STATE_FINISHED) & (it->curveRaster->state == CURVEDATA_STATE_FINISHED))
    {
        queueBuffers.erase(std::find(queueBuffers.begin(), queueBuffers.end(), *(it->curveBuffer)));  // <-- THIS DOESNT WORK. CHECK BELOW FOR ERROR MESSAGE (1)
        queueStates.erase(it);
    }
    //////////////////////////////////////////////////////////////////////////
}

(1) This is the message I get from the compiler:

(1)这是我从编译器得到的消息:

Error   error C2678: binary '==' : no operator found which takes a left-hand operand of type 'const BufferPoint' (or there is no acceptable conversion) c:\program files (x86)\microsoft visual studio 11.0\vc\include\xutility 2956

3 个解决方案

#1


1  

If you have a real iterator referencing an element in your vector, the removal is trivial::

如果你有一个真正的迭代器引用你的向量中的元素,删除是微不足道的::

std::vector<int>::iterator myIter = ... get iterator to your element ...
buffer.erase(myIter);

If instead you have a value prospect and you want the first element of that value removed:

相反,如果您有价值潜在客户,并且您希望删除该值的第一个元素:

int myVal = ... whatever the value is ...
buffer.erase(std::find(buffer.begin(), buffer.end(), myVal));

Finally, if you want to remove all elements matching the value prospect:

最后,如果要删除与值前景匹配的所有元素:

int myVal = ... whatever the value is ...
buffer.erase(std::remove(buffer.begin(), buffer.end(), myVal), buffer.end());

I hazard to suggest one of these will likely fit the bill far better than what you're currently doing. Judging by the input on other answers, I suggest you try the last one. If you're the least-bit curious how it works, think of it as doing the following:

我冒险建议其中一个可能比你目前正在做的更好。从其他答案的输入来看,我建议你试试最后一个。如果你对它的工作方式一点也不感兴趣,那就把它想象成如下:

Given this sequence:

鉴于此顺序:

1 3 4 2 3 5 6 3 7

Now suppose you want to remove all the 3's. The std::remove will transform your vector to the following via element swaps

现在假设您要删除所有3个。 std :: remove将通过元素交换将您的向量转换为以下内容

1 4 2 5 6 7 3 3 3
return it --^

The buffer.erase() method then erases from the returned iterator to the end of the sequence leaving you with simply:

然后,buffer.erase()方法从返回的迭代器中删除到序列的末尾,只需:

1 4 2 5 6 7

This is commonly called the remove/erase idiom

这通常称为删除/擦除习语


EDIT: OP requests how to do this with his custom structure.

编辑:OP请求如何使用他的自定义结构执行此操作。

In you case, just define the following after the BufferPoint definition:

在您的情况下,只需在BufferPoint定义之后定义以下内容:

struct BufferPoint {int x; int y; float pressure; };

inline bool operator ==(const BufferPoint& lhs, const BufferPoint& rhs)
{
    return lys.x == rhs.x && lhs.y == rhs.y;
}

I wasn't sure if you wanted pressure in that equality comparison. If so, add it in as a condition, but note floating point roundoff is a pesky thing to deal with. if you can avoid it, do so. This is probably the simplest way to get what you're after.

我不确定你是否希望在平等比较中有压力。如果是这样,请将其添加为条件,但注意浮点舍入是一个令人讨厌的事情。如果你能避免它,那就去做吧。这可能是获得你所追求的最简单的方法。

#2


1  

First std::vector has no function member called .remove, it has .erase. Second, after each erase all iterators will be get invalid. So you should the updated iterator returns from .erase method.

第一个std :: vector没有名为.remove的函数成员,它有.erase。其次,每次擦除后,所有迭代器都将无效。所以你应该从.erase方法返回更新的迭代器。

Iterators and references to the erased elements and to the elements between them and the end of the container are invalidated. The past-the-end iterator is also invalidated.

对迭代元素及其与容器末尾之间的元素的迭代器和引用无效。过去的迭代器也是无效的。

for (vector<int>::iterator b=buff.begin(); it!=buffer.end(); )
{

   if(*b == myRef) 
       b = buffer.erase(b);
   else 
      ++b;
}

#3


0  

You should use erase method,try this

你应该使用擦除方法,试试这个

vector<int> buffer;

int myRef ; //reference to one element of 'buffer'

for(std::vector<int>::iterator b = buffer.begin(); b != buffer.end(); ++b)
{
  if(*b == myRef)       // <-- THIS CLEARLY DOESNT WORK
  {
    b = buffer.erase(b);// <-- REMOVE THE FOUND ELEMENT FROM THE VECTOR
    b--;
  }
}

#1


1  

If you have a real iterator referencing an element in your vector, the removal is trivial::

如果你有一个真正的迭代器引用你的向量中的元素,删除是微不足道的::

std::vector<int>::iterator myIter = ... get iterator to your element ...
buffer.erase(myIter);

If instead you have a value prospect and you want the first element of that value removed:

相反,如果您有价值潜在客户,并且您希望删除该值的第一个元素:

int myVal = ... whatever the value is ...
buffer.erase(std::find(buffer.begin(), buffer.end(), myVal));

Finally, if you want to remove all elements matching the value prospect:

最后,如果要删除与值前景匹配的所有元素:

int myVal = ... whatever the value is ...
buffer.erase(std::remove(buffer.begin(), buffer.end(), myVal), buffer.end());

I hazard to suggest one of these will likely fit the bill far better than what you're currently doing. Judging by the input on other answers, I suggest you try the last one. If you're the least-bit curious how it works, think of it as doing the following:

我冒险建议其中一个可能比你目前正在做的更好。从其他答案的输入来看,我建议你试试最后一个。如果你对它的工作方式一点也不感兴趣,那就把它想象成如下:

Given this sequence:

鉴于此顺序:

1 3 4 2 3 5 6 3 7

Now suppose you want to remove all the 3's. The std::remove will transform your vector to the following via element swaps

现在假设您要删除所有3个。 std :: remove将通过元素交换将您的向量转换为以下内容

1 4 2 5 6 7 3 3 3
return it --^

The buffer.erase() method then erases from the returned iterator to the end of the sequence leaving you with simply:

然后,buffer.erase()方法从返回的迭代器中删除到序列的末尾,只需:

1 4 2 5 6 7

This is commonly called the remove/erase idiom

这通常称为删除/擦除习语


EDIT: OP requests how to do this with his custom structure.

编辑:OP请求如何使用他的自定义结构执行此操作。

In you case, just define the following after the BufferPoint definition:

在您的情况下,只需在BufferPoint定义之后定义以下内容:

struct BufferPoint {int x; int y; float pressure; };

inline bool operator ==(const BufferPoint& lhs, const BufferPoint& rhs)
{
    return lys.x == rhs.x && lhs.y == rhs.y;
}

I wasn't sure if you wanted pressure in that equality comparison. If so, add it in as a condition, but note floating point roundoff is a pesky thing to deal with. if you can avoid it, do so. This is probably the simplest way to get what you're after.

我不确定你是否希望在平等比较中有压力。如果是这样,请将其添加为条件,但注意浮点舍入是一个令人讨厌的事情。如果你能避免它,那就去做吧。这可能是获得你所追求的最简单的方法。

#2


1  

First std::vector has no function member called .remove, it has .erase. Second, after each erase all iterators will be get invalid. So you should the updated iterator returns from .erase method.

第一个std :: vector没有名为.remove的函数成员,它有.erase。其次,每次擦除后,所有迭代器都将无效。所以你应该从.erase方法返回更新的迭代器。

Iterators and references to the erased elements and to the elements between them and the end of the container are invalidated. The past-the-end iterator is also invalidated.

对迭代元素及其与容器末尾之间的元素的迭代器和引用无效。过去的迭代器也是无效的。

for (vector<int>::iterator b=buff.begin(); it!=buffer.end(); )
{

   if(*b == myRef) 
       b = buffer.erase(b);
   else 
      ++b;
}

#3


0  

You should use erase method,try this

你应该使用擦除方法,试试这个

vector<int> buffer;

int myRef ; //reference to one element of 'buffer'

for(std::vector<int>::iterator b = buffer.begin(); b != buffer.end(); ++b)
{
  if(*b == myRef)       // <-- THIS CLEARLY DOESNT WORK
  {
    b = buffer.erase(b);// <-- REMOVE THE FOUND ELEMENT FROM THE VECTOR
    b--;
  }
}