짧은
변환 함수는 operator int()
위에 연타 의해 선택된 operator bool() const
때문에b
const 정규화되지 않았기 반면 bool의 변환 연산자는 그렇습니다.
짧은 이유는 다음과 같이 변환 b
할 때 과부하 해결을위한 후보 함수 (암시 적 객체 매개 변수 사용) bool
가
operator bool (B2 const &);
operator int (B2 &);
두 번째 것이 더 나은 경기입니다. b
는 const 규정이 아니기 입니다.
두 기능이 동일한 자격을 공유하는 경우 (둘 다 const
또는 아님)을operator bool
직접 변환을 제공하므로이 선택됩니다.
캐스트 표기법을 통한 변환, 단계별 분석
부울 ostream 삽입 기 (std :: basic_ostream :: operator << (bool val) as per [ostream.inserters.arithmetic])가로 변환 된 값으로 호출된다는 데 동의 b
하면bool
우리가 전환 가능 파고 .
1. 캐스트 표현
b를 bool로 캐스트
(bool)b
평가하다
static_cast<bool>(b)
당 C ++ 11 / 4 5.4 [expr.cast] 보낸const_cast
적용 할 수 없다 (추가 또는 여기 CONST 제거되지 않음).
이 정적 변환은 당 허용되는 , C ++ 4분의 11 5.2.9 [expr.static.cast] , 경우에 bool t(b);
발명 된 변수 t가 잘 형성되어 대한. 이러한 문을 C ++ 11, 8.5 / 15 [dcl.init]에 따라 직접 초기화라고 합니다.
2. 직접 초기화 bool t(b);
가장 적게 언급 된 표준 단락의 16 절 은 다음과 같이 말합니다 (강조 표시).
이니셜 라이저의 의미는 다음과 같습니다. 대상 유형은 초기화되는 개체 또는 참조의 유형이고 소스 유형은 이니셜 라이저 표현식의 유형입니다.
[...]
[...] 소스 유형 이 (가능하면 cv-qualified) 클래스 유형 인 경우 변환 함수 가 고려됩니다.
적용 가능한 변환 기능이 열거되고 과부하 해결을 통해 최상의 기능이 선택됩니다.
2.1 어떤 변환 기능을 사용할 수 있습니까?
사용 가능한 변환 함수는 다음 operator int ()
과 operator bool() const
같습니다. C ++ 11부터 12.3 / 5 [class.conv] 는 다음을 알려줍니다.
파생 클래스의 변환 함수는 두 함수가 동일한 형식으로 변환되지 않는 한 기본 클래스의 변환 함수를 숨기지 않습니다.
반면 C ++ 11 13.3.1.5/1 [over.match.conv] 주 :
S 및 기본 클래스의 변환 함수가 고려됩니다.
여기서 S는 변환 될 클래스입니다.
2.2 적용 가능한 변환 기능은 무엇입니까?
C ++ 11, 13.3.1.5/1 [over.match.conv] (강조 내) :
1 [...] "cv1 T"가 초기화되는 객체의 유형이고 "cv S"가 초기화 표현식의 유형이고 S가 클래스 유형이라고 가정하면 후보 함수는 다음과 같이 선택됩니다. S 및 기본 클래스의 기능이 고려됩니다. S 및 yield type T 내에 숨겨지지 않은 비명 시적 변환 함수 또는 표준 변환 시퀀스를 통해 유형 T로 변환 할 수있는 유형 은 후보 함수입니다.
따라서 operator bool () const
이 숨겨져되지 않기 때문에 적용 B2
과를 산출한다 bool
.
마지막 표준 견적에서 강조된 부분 은 표준 변환 시퀀스를 통해 bool로 변환 할 수있는 유형 operator int ()
이기 때문에 사용하는 변환과 관련 int
이 있습니다. 행 변환 int
으로는 bool
심지어 시퀀스 그러나 당 허용되는 일반 직접 변환 인 C ++ 11 4.12 / 1 conv.bool]
산술, 범위가 지정되지 않은 열거, 포인터 또는 멤버 유형에 대한 포인터의 prvalue는 bool 유형의 prvalue로 변환 될 수 있습니다. 0 값, 널 포인터 값 또는 널 멤버 포인터 값은 false로 변환됩니다. 다른 값은 true로 변환됩니다.
이것은 operator int ()
또한 적용 가능 하다는 것을 의미합니다 .
2.3 어떤 변환 기능이 선택됩니까?
적절한 변환 함수의 선택은 과부하 해결 ( C ++ 11, 13.3.1.5/1 [over.match.conv] )을 통해 수행됩니다 .
과부하 해결은 호출 할 변환 기능을 선택하는 데 사용됩니다.
클래스 멤버 함수의 오버로드 해결과 관련하여 특별한 "특징"이 하나 있습니다. 암시 적 개체 매개 변수입니다.
당 C ++ 11 13.3.1 [over.match.funcs] ,
[...] 정적 및 비 정적 멤버 함수에는 모두 암시 적 개체 매개 변수가 있습니다 [...]
여기서 4- 절에 따른 비 정적 멤버 함수에 대한이 매개 변수의 유형은 다음과 같습니다.
여기서 X는 함수가 멤버 인 클래스이고 cv는 멤버 함수 선언에 대한 cv 자격입니다.
즉 , 변환 함수에 의한 초기화에서 ( C ++ 11, 13.3.1.5/2 [over.match.conv]에 따라 ),
인수 목록에는 이니셜 라이저 표현식 인 하나의 인수가 있습니다. [참고 :이 인수는 변환 함수의 암시 적 개체 매개 변수와 비교됩니다. —end note]
과부하 해결을위한 후보 함수는 다음과 같습니다.
operator bool (B2 const &);
operator int (B2 &);
자격 변환이 필요하기 때문에 operator int ()
유형의 상수가 아닌 개체를 사용하여 변환이 요청되는 경우 분명히 더 나은 일치 입니다.B2
operator bool ()
두 변환 함수가 동일한 const 자격을 공유하면 해당 함수의 오버로드 해결이 더 이상 트릭을 수행하지 않습니다. 이 경우 전환 (시퀀스) 순위가 적용됩니다.
3. operator bool ()
두 변환 함수가 동일한 const 자격을 공유 할 때 왜 선택됩니까?
행 변환 B2
하려면 bool
사용자 정의 변환 시퀀스 (인 C ++ 11 13.3.3.1.2 / 1 over.ics.user] )
사용자 정의 변환 시퀀스는 초기 표준 변환 시퀀스, 사용자 정의 변환, 두 번째 표준 변환 시퀀스로 구성됩니다.
[...] 사용자 정의 변환이 변환 함수에 의해 지정된 경우 초기 표준 변환 시퀀스는 소스 유형을 변환 함수의 암시 적 개체 매개 변수로 변환합니다.
C ++ 11, 13.3.3.2/3 [over.ics.rank]
[...]은 더 나은 변환 시퀀스와 더 나은 변환 관계를 기반으로 암시 적 변환 시퀀스의 부분 순서를 정의합니다.
[...] 사용자 정의 변환 시퀀스 U1은 동일한 사용자 정의 변환 함수 또는 생성자 또는 집계 초기화를 포함하고 U1의 두 번째 표준 변환 시퀀스가 다음보다 나은 경우 다른 사용자 정의 변환 시퀀스 U2보다 나은 변환 시퀀스입니다. U2의 두 번째 표준 변환 시퀀스입니다.
두 번째 기준 변환 경우가 operator bool()
있다 bool
에 bool
있는 경우는 제 표준 변환 반면 (신원 변환) operator int ()
인 int
에 bool
부울 변환된다.
따라서 operator bool ()
두 변환 함수가 동일한 const 자격을 공유하는 경우를 사용하는 변환 시퀀스 가 더 좋습니다.