2014-02-27 5 views
14

는, 출력은이 왜 명시 적으로 부울() 변환이 문맥 전환에 일어나는가

int A::operator int() 
bool() 
int A::operator int() 
int() 

하지

bool A::operator _Bool() 
bool() 
int A::operator int() 
int() 
입니다

내가 뭘 기대했는지 (그리고 주석 처리 된 부분의 주석을 풀면 얻을 수있는 것).

그래서 const-bool로 변환하는 것보다 const-int가 아닌 우선 순위로 변환하는 규칙은 무엇입니까?

+0

컴파일러는 무엇입니까? 'const 연산자 int() const' 컴파일이 실패합니다. –

+0

컴파일러가 clang-3.4입니다. – wimalopaan

+1

질문 제목을 업데이트하여 이중 음수를 제거 할 수 있습니까? 나는 그것을 스스로 할 것이지만, 나는 "하지 않는다"또는 "하지 않는다"를 제거 할 지 확신하지 못한다. 아니면 둘 다? – icabod

답변

6

참조 바인딩에서 오버로드 확인을 수행 할 때 더 적은 자격이 부여 된 유형이 선호됩니다. 멤버 함수 (13.3.1.1.1p2)의 내재 된 오브젝트 파라미터에 객체를 결합하는 결합 기준이다

struct X { 
    void f() const; 
    void f(); 
}; 
void g(const X& a, X b) { 
    a.f(); // calls X::f() const 
    b.f(); // calls X::f() 
} 

주 (13.3.3.1이 예들과 함께 논의된다 13.3.3.2p3 .4).

변환 연산자는 오버로드 해결 (13.3p2)의 목적으로 멤버 함수 (13.3.1.5)로 처리됩니다. bool으로 문맥 변환은 초기화 (4p4)의 의미를가집니다.

변환 연산자의 반환 형식에 필요한 변환은 이후에만 으로 간주되며 변환 연산자 자체 (13.3.3p1) 사이의 과부하 해결을 고려해야합니다.

해결 방법은 모든 변환 연산자가 특히 const- 품질, 특히 스칼라 유형과 동일하도록 보장하는 것입니다.

+0

* "중요한 것은 변환 연산자의 반환 유형에 필요한 모든 변환은 변환 연산자 자체 (13.3.3p1) 사이의 과부하 해결을 고려한 후에 만 ​​고려됩니다."* 음, *로 시작하는 글 머리 기호가 있습니다. "컨텍스트는 초기화입니다 사용자 정의 변환 (user-defined conversion) "*이 의미하는 것으로 보입니다. +1 – dyp

+0

@dyp 여기에는 UDCS가 없습니다. 왜냐하면 우리는 다른 함수들 사이에서'X' 인자로 해결하지 않기 때문입니다. 우리가'f (bool);을 가졌다면 UDCS가있을 것이다. f (플로트); X x; f (x); 그리고 실제로 그러한 UDCS는 모호합니다. – ecatmur

+0

'A'에서'bool '로의 전체 변환은 (OP의 예에서) UDCS이지만, 과부하 해결은 "너무 일찍"적용됩니다. 여기서 UDC가'A '에서'bool '로 변환해야합니다. isn 고려하지 않았지만 실행 가능한 함수를 정의하는 데만 사용되었습니다 (따라서 묵시적 개체 인수에 대한 SCS 만 과부하 해결로 간주됩니다). – dyp

4

const-bool로 변환하는 것보다 const-int가 아닌 우선 순위로 변환하는 규칙은 무엇입니까?

비 const 오브젝트의 const 멤버 기능을 사용하려면 비 const 오브젝트를 const 오브젝트로 변환해야합니다. 그렇기 때문에 operator int()operator bool() const과 더 일치합니다. 당신이 INT 연산자를 제거 할 경우

, 그것은 조금 명확하게하기 위해, 정말로 처음 부울 컨텍스트 (첫 번째 경우)에 발생하는 것은 이것이다 :

:

if (const_cast<const A&>(a).operator bool()) { 

대신, 무슨 일이있다

if (a.operator int()) 
+1

OP 질문에 주석 처리 된 연산자가 명시 적이며 'const'로 인해 동작이 변경되기 때문에이 답변은 실제로 작동하지 않습니다. 또한 명시 적'연산자 bool '은 부울 컨텍스트 (예 :'if')에서 형 변환하지 않고 사용할 수 있습니다. 이것은 C++ 11에서 안전한 bool 관용구를 구현하는 매우 쉬운 방법입니다. – Excelcius

+0

C++ 11에서 expilicit-bool-idiom을 올바르게 사용하려면 bool 연산자의 const 버전과 non const 버전을 모두 구현해야합니다. 다른 전환 연산자가 실행되는 것을 막기 위해서입니까? – wimalopaan

+0

이 과부하 해결에 대한 순위 결정 방식을 이해하지 못했습니다. 일반적으로 'A'를'A const '에 바인딩하는 것은 직접 참조 바인딩이므로 정확한 일치로 간주됩니다. 따라서 묵시적인 개체 인수는 두 경우 모두 암시 적 개체 매개 변수와 정확하게 일치해야합니다. 그런 다음 두 가지 모두에 대해 UDC가 있지만 'int'로의 변환을 위해 부울 변환이 수행됩니다. 분명히, 그것은 컴파일러에서 일어나는 것이 아니며, 묵시적 객체 인수의 일치는 어떻게 든 다르게 순위가 매겨집니다. – dyp

관련 문제