2011-09-02 6 views
19

필자는 Qt의 공유 데이터 포인터와 비슷한 것을 랩핑하려고 시도했다. 테스트 할 때 const 함수를 호출해야 할 때 비 const 버전은 선택한 대신. 내가 여기에 C + +0 옵션을 사용하여 컴파일하고있어비 const 버전이 아닌 const 함수 호출하기

는 최소한의 코드입니다 :

struct Data { 
    int x() const { 
     return 1; 
    } 
}; 

template <class T> 
struct container 
{ 
    container() { 
     ptr = new T(); 
    } 


    T & operator*() { 
     puts("non const data ptr"); 
     return *ptr; 
    } 

    T * operator->() { 
     puts("non const data ptr"); 
     return ptr; 
    } 

    const T & operator*() const { 
     puts("const data ptr"); 
     return *ptr; 
    } 

    const T * operator->() const { 
     puts("const data ptr"); 
     return ptr; 
    } 

    T* ptr; 
}; 

typedef container<Data> testType; 

void testing() { 
    testType test; 
    test->x(); 
} 

당신이 볼 수 있듯이이 DATA.X 인 CONST 기능, 그래서 연산자 ->해야한다라고 const 하나. 그리고 non-const one을 주석 처리하면 오류없이 컴파일되므로 가능합니다. 그러나 내 터미널 인쇄 :

"비 const를 데이터 PTR"

IT는 GCC 버그 (나는 4.5.2를)인가, 또는 거기에 내가 부족 뭔가?

답변

17

const -ness 만 다른 두 가지 오버로드가있는 경우 컴파일러는 *thisconst인지 여부에 따라 호출을 해결합니다. 예제 코드에서 testconst이 아니므로 const 오버로드가 호출됩니다.

당신이 이런 짓을하는 경우 :

testType test; 
const testType &test2 = test; 
test2->x(); 

test2const 때문에 당신이 다른 과부하가 호출되는 것을 볼 수 있습니다.

+2

그래서 const 오버로드를 호출 할 수 있다고하더라도 컴파일러는 객체가 const로 선언되지 않은 경우 non-const 과부하를 선호합니다. – coyotte508

+2

@ coyotte508 : 정확하게. nonconst' 과부하가 더 나은 일치로 간주됩니다. –

1

그러나 testType은 const 개체가 아닙니다.

따라서 멤버의 비 const 버전을 호출합니다.
메서드에 정확히 동일한 매개 변수가 있으면 호출 할 버전을 선택해야합니다 (이 매개 변수는 숨겨진 매개 변수를 사용합니다). 이 경우 const가 아니므로 비 const 메소드를 얻을 수 있습니다.

const가 아닌 개체에 const 메서드를 호출 할 수 있으므로 x() 호출에 영향을주지 않습니다.

2

Data::x이 상수 함수인지 여부는 중요하지 않습니다. 호출 된 연산자는 container<Data> 클래스에 속하며 Data 클래스가 아니며 해당 인스턴스가 상수가 아니므로 상수 연산자가 호출됩니다. 사용 가능한 상수 연산자 만 있거나 클래스의 인스턴스 자체가 상수이면 상수 연산자가 호출되었을 것입니다.

4

test은 const가 아닌 개체이므로 컴파일러에서 가장 일치하는 항목을 찾습니다. 비 const 버전. static_cast<const testType&>(test)->x();

편집 : 당신은 static_cast 생각과 const와를 적용 할 수 있습니다 제쳐두고, 당신은 아마도 몇 가지 이상한 특질 컴파일러 거기에 당신이 당신이 당신의 코드를 다시 방문해야 컴파일러 버그를 발견했다고 생각하는 시간의 99.9 %를 의심로 실제로 표준을 따르고 있습니다.

+0

+1 "컴파일러에서 버그를 발견하지 못했습니다."주석 – MikMik