There is a class "Camera". It has a static list of all the cameras created:

private:static std::vector<Camera> cameras;

In the constructor of this class, I put "myself" (this) in this list like this:

 Camera::cameras.push_back(*this); 

I want to remove "myself" from this list in the destructor. Trying to do this:

 cameras.erase(std::find(cameras.begin(), cameras.end(), *this)); 

Gives a compilation error:

 Ошибка C2678 бинарный "==": не найден оператор, принимающий левый операнд типа "Camera" (или приемлемое преобразование отсутствует) 

What am I doing wrong? I think you need to redefine the operator == to compare two cameras. But is that the problem?

  • one
    And you put a pointer in the vector, not an object. std::vector<Camera*> and .push_back(this); - gil9red
  • Yes How do you mostly store? - cvvvlad
  • one
    Yes, in different ways, depending on the situation. See, if you put pointers, the vector compares by pointers, if as objects, then create an operator == so that the vector can compare as objects. - gil9red
  • Those. It's all the same in the operator "==". Thank! That was the answer !! - cvvvlad
  • adding objects to the vector by value, there is a copy of it. It is possible that when you delete, nothing will be removed from the vector (it all depends on how the == operator is written) - KoVadim

2 answers 2

Here

 Camera::cameras.push_back(*this); 

you make a copy of your object in the vector. When deleting, the vector tries to compare objects , not pointers. For this, it needs a comparison operator.

The most reasonable thing is not to copy your cameras, to copy addresses. Those. use

 static std::vector<Camera*> cameras; 

In this case, no extra entities will be created, which is already good.

If you still need to store copies, then the second option is to define a comparison operator, and the third is to use find_if with the corresponding predicate (right up to lambda).

But the transfer of addresses, in my opinion, the most effective solution.

    I will add @Harry.

    If you don’t want some malicious program to put nullptr there, you can organize the vector of "links":

     private:static std::vector<std::reference_wrapper<Camera>> cameras; 

    And put there a link to the class:

     Camera::cameras.push_back(std::ref(*this)); 

    Well, you can search for the desired item by its address:

     cameras.erase(std::find_if(cameras.begin(), cameras.end(), [this](std::reference_wrapper<Camera> wrapper) { return &wrapper.get() == this; })); 

    It's still possible to put a mess there, but it will be more difficult :)