2017-09-27 1 views
10

보통 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 
} 

이진 "=="어떤 연산자는 형 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 
+0

예제에서'const =='왼쪽 피연산자가'* this'가되도록'operator =='가 선언되어 있지 않기 때문에'* 구성 == foo2' 또는'* pToRenderJob == foo2'를 할 수 없습니다 . 클래스가'void f();'함수를 가지고 있다면 똑같은 것이 될 것입니다 - 당신은'구성 -> f()'또는'pToRenderJob-> f()'를 할 수 없습니다. 하지만 그 함수를'void f() const;'로 변경하면 두 함수 모두 괜찮을 것입니다. – aschepler

+0

감사합니다. 많은 규칙들이 서서히 설정되고 있습니다. – Zebrafish

+0

클래스 내에'renderJob_ID'를 정의해야합니다 :'int renderJob_ID {}'. 초기화되지 않은 객체를 떠나는 것은 조숙 한 최적화입니다. 귀하의 예제에서 foo.renderJob_ID와 foo.renderJob_ID는 * indeterminate value *를 가지고 있고,'std :: vector renderJobs (10)'을 선언하여 10 개의 renderJobs 벡터를 생성하면이 10 개의 모든 객체는 renderJob_ID에 * 불확정 값 *. 따라서 연산자 == 인수에 const를 추가 한 후에도 코드는 계속 작동하지 않습니다. – Oliv

답변

14

당신은 당신의 const 예선을 떠났다.

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

네, 고마워요. 특히 const RenderJob은 함수 뒤에있는 것이 아닙니다. 나는 이것을 얻지 못한다. 나는 operator == overload 때문에 그것들을 직접 비교할 수있다. std :: does not find operator == function? – Zebrafish

+4

둘 다 const 여야합니다. 컴파일러가 const 데이터에 대한 연산자를 찾고있을 때 const 동작을 보장하지 않는 연산자를 고려하지 않습니다. –

+0

지금 당장 이해 하겠지만, 질문에 대한 나의 추가 예제에서 오른손은 비 const이므로 비 const 연산자 ==를 호출해야한다고 생각합니다. 물론 const와 비 const. – Zebrafish

5

const 수정 문제와 비슷한 모양입니다. 다음과 같이 시도해보십시오.

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

일시적인 것이 아니거나 const 자격이없는 일반 개체를 전달하기 때문에 직접 비교 작업을 수행했습니다. std::find을 사용하면 비교 함수가 (적어도 일반적으로) 컬렉션에서 개체에 대한 참조를받습니다 (일반적으로 const 한정) 따라서 const 한정 참조를받을 수 있어야합니다.

+1

오, 알겠습니다. 효과가있었습니다. 그러나, 나는 그들 자신을 비교할 수 있었다. std :: compare에서 compare 함수가 연산자 == 함수를 사용하지 않습니까? – Zebrafish

+1

@Zebrafish'find'는 const 참조로 비교할 값을 취합니다. –

3

하지만 여전히 이해가되지 않습니다, 위의 예에서, 오른쪽은 비 constoperator==로 이동해야하는 일정하지 않은, foo2이다. const과 비 const을 비교할 수없는 일반적인 규칙이없는 한.

constconst 개체를 비교할 수없는 언어 규칙은 없습니다. 적절한 const 한정자를 사용하여 비교할 수 있는지 확인해야합니다.

라인은

*pToRenderJob == foo2; 

pToRenderJob가 비 const 멤버 함수를 호출 할 수 없기 때문에 동작하지 않는

pToRenderJob->operator==(foo2); 

동일하다. foo2은 여기에서 문제가되지 않습니다.당신이

foo2 == *pToRenderJob 

를 사용하는 경우

은 당신의 함수는 비 const 참조를 기대하면서 함수의 인수가 const 객체이기 때문에 또한 문제 즉

foo2.operator==(*pToRenderJob) 

에 해당합니다. 다시 한번 foo2은 문제가되지 않습니다.

함수에게 const 멤버 함수를 제작하고 const 기준은 조작자의 양측에 비 constconst 및 개체의 모든 조합이 어떤 문제없이 사용될 수 있음을 확실하게 인수를 결정.

+0

그것은 매우 흥미 롭습니다. 그래서 * pToRenderJob == foo2에서 실제 함수 const를 만들 때 작동했습니다. 매우 흥미롭고 미묘한 규칙. – Zebrafish

+0

@ 제브라 피쉬. 이 규칙에 익숙해 지려면 시간이 좀 걸리지 만 그 이상의 언어를 더 깊이 이해하면 규칙이 이해되기 시작합니다. –

관련 문제