Почему этот std:: find не может сравниться с этими объектами

Обычно, когда я делаю std:: find, я помещаю предикат в качестве третьего аргумента, но на этот раз я думал, что сделаю это по-другому, я не понимаю, почему он не работает.

#include <iostream>
#include <vector>
#include <algorithm>

struct RenderJob
{
    RenderJob() {};
    int renderJob_ID;
    bool operator==(RenderJob& rhs) { return rhs.renderJob_ID == this->renderJob_ID; }
};

int main()
{
    RenderJob foo;
    RenderJob foo2;
    foo == foo2; // Works

    std::vector<RenderJob> renderJobs;

    std::find(renderJobs.begin(), renderJobs.end(), foo); // Doesn't work
}

binary "==" не найден оператор, который принимает левый операнд тип RenderJob (или нет приемлемого преобразования)

Изменить:: Хорошо спасибо за ответы. Вот несколько примеров того, почему он терпит неудачу

    RenderJob foo;
    RenderJob foo2;
    foo == foo2; // Works

    std::vector<RenderJob> renderJobs;

    std::vector<RenderJob>::const_iterator constit = renderJobs.begin();

    *constit == foo2;  // Doesn't work

Еще проще в качестве иллюстрации:

 const RenderJob* pToRenderJob;

*pToRenderJob == foo2;  // This fails because the pointed to 
                        // object is const, and cannot call the 
                        // operator== function because the actual function
                        // definition is not const. 

Если бы это было наоборот:

foo2 == *pToRenderJob; // This would fail because the 
                        // operator==(RenderJob&) the actual argument 
                        // is not const. Very subtle rules

Ответ 1

Вы оставили свои квалификаторы const.

bool operator==(const RenderJob& rhs) const { ... }

Ответ 2

Похоже на проблему состязательности. Попробуйте что-то вроде этого:

bool operator==(RenderJob const &rhs) const { 
    return rhs.renderJob_ID == this->renderJob_ID; 
}

Выполнение сравнения работало, потому что вы просто проходили простые объекты, которые не были временными, и они не были квалифицированы. С помощью std::find функция сравнения будет (по крайней мере, обычно) получать ссылку на объект в коллекции (который обычно будет иметь значение const), поэтому он должен иметь возможность получать опорную константу.

Ответ 3

Но это все еще не имеет смысла, в приведенном выше примере правая часть foo2, которая не является константой, которая должна перейти к не const operator==. Если не существует общего правила, что const и non const нельзя сравнивать.

На языке нет правила, что нельзя сравнивать объекты const и non const. Вы должны убедиться, что их можно сравнить с помощью соответствующих const квалификаторов.

Линия

*pToRenderJob == foo2;

эквивалентно

pToRenderJob->operator==(foo2);

Это не работает, поскольку pToRenderJob не может использоваться для вызова функции-члена не const. foo2 здесь не проблема.

Если вы используете

foo2 == *pToRenderJob

он эквивалентен

foo2.operator==(*pToRenderJob)

Это также проблема, поскольку аргумент функции является объектом const, в то время как ваша функция ожидает ссылку const. Еще раз, foo2 не проблема.

Выполнение функции a const функции-члена и утверждение аргумента a const гарантирует, что любые комбинации объектов const и non const с обеих сторон оператора могут быть использованы без каких-либо проблем.