0

I am working on my C++ home-project and got into trouble with the following C2676 error:

binary '==': 'std::reference_wrapper<Interactable>' does not define this operator or a conversion to a type acceptable to the predefined operator

I have this in my World class and I am pretty sure the find is what invokes the above error:

void RemoveObject(Interactable* object)
{
    if (!object) return;
    auto itr = std::find(dynamicWorldObjects.begin(), dynamicWorldObjects.end(), *object);
    if (itr == dynamicWorldObjects.end()) return;
    dynamicWorldObjects.erase(itr);
}

And my Interactable looks like this:

class Interactable
{
public:
    Vector2 Position;
    Vector2 Velocity;
    Shape Shape;

    Interactable(const std::string& path, SDL_Renderer* rend, int id)
    {
        _id = id;
        SDL_Surface* surface = IMG_Load(path.c_str());
        _texture = SDL_CreateTextureFromSurface(rend, surface);
        _destination.w = surface->w;
        _destination.h = surface->h;
        SDL_FreeSurface(surface);
    }

    ~Interactable()
    {
        SDL_DestroyTexture(_texture);
    }

    void Render(SDL_Renderer* rend)
    {
        _destination.x = Position.X;
        _destination.y = Position.Y;

        SDL_RenderCopy(rend, _texture, NULL, &_destination);
    }

    int GetID() const
    {
        return _id;
    }

    bool operator == (const Interactable& A) const
    {
        return this->GetID() == A.GetID();
    }

private:
    SDL_Rect _destination;
    SDL_Texture* _texture;
    int _id;
};

My question is how am I able to resolve the comparison of these reference_wrappers? Am I missing something or my approach went wrong?

Thank you for the input!

Edit1: My World class starts with this:

class World
{
private:
    std::vector<std::reference_wrapper<Interactable> > staticWorldObjects;
    std::vector<std::reference_wrapper<Interactable> > dynamicWorldObjects;
    int _id;

public:
    World()
    {
        staticWorldObjects = std::vector<std::reference_wrapper<Interactable> >();
        dynamicWorldObjects = std::vector<std::reference_wrapper<Interactable> >();
        _id = 0;
    }
...
}```
Sarungard
  • 1
  • 1
  • How is `dynamicWorldObjects` defined? – john Aug 21 '22 at 12:56
  • Certainly `bool operator == (Interactable& A)` should be defined `bool operator == (const Interactable& A) const` and `int GetID()` should be defined `int GetID() const`. That might solve your problem, but not sure. – john Aug 21 '22 at 12:58
  • You are right I was in a hurry and left them out, thank you for pointing it out. Edited the post with how it is defined. – Sarungard Aug 21 '22 at 13:01

2 Answers2

0

Not totally sure about std::reference_wrapper but maybe this will help.

The first change needed is this

auto itr = std::find(dynamicWorldObjects.begin(), dynamicWorldObjects.end(), 
    *object);

dynamicWorldObjects is a vector of Interactable but object (despite it's name) is a pointer, therefore you need *object. Or you could change RemoveObject so that it takes a reference instead of a pointer. Perhaps this is the better change.

The second change concerns the const-correctness of Interactable. This change might not be strictly necessary to resolve the current problem but it will bite you sooner or later, so it should be fixed now.

Change

int GetID()
{
    return _id;
}

to

int GetID() const
{
    return _id;
}

and

bool operator == (Interactable& A)
{
    return this->GetID() == A.GetID();
}

to

bool operator == (const Interactable& A) const
{
    return this->GetID() == A.GetID();
}
john
  • 85,011
  • 4
  • 57
  • 81
  • Even though I tried both method you wrote and even other workarounds, the compiler still says the same error. It's like reference_wrapper can't compare my classes. – Sarungard Aug 21 '22 at 13:25
  • @Sarungard I took the above code and was able to compile it without problems. I had to remove the SDL stuff since I don't have that installed,and I made `dynamicWorldObjects` a global variable but otherwise no problems. – john Aug 21 '22 at 16:13
  • @Sarungard If you can't get it working then try to produce a [mre] that anyone can try (i.e. with out SDL stuff) that has the error you have, and post it (perhaps as a new question). – john Aug 21 '22 at 16:14
0

I found the answer! It was with the wrong implementation of the == operator of Interactable class. What I did was to define the operator OUTSIDE of the class and made a friendly declcaration INSIDE.

Nevertheless thank you john for the help!

Sarungard
  • 1
  • 1