gcc의 is_nothrow_constructible 구현에 static_cast가 필요한 이유는 무엇입니까?


11

GCC 구현에서 가져온 type_traits이유는 static_cast무엇입니까?

template <typename _Tp, typename... _Args>
struct __is_nt_constructible_impl
    : public integral_constant<bool, noexcept(_Tp(declval<_Args>()...))> {};

template <typename _Tp, typename _Arg>
struct __is_nt_constructible_impl<_Tp, _Arg>
    : public integral_constant<bool,
                               // Why is `static_cast` needed here?
                               noexcept(static_cast<_Tp>(declval<_Arg>()))> {};

그 불일치 이상한 보인다
궤도의 밝기 경주를

4
관련 libstdc ++ 메일 링리스트
Orbit의 Lightness Races

답변:


12

발명 된 변수 선언 인 경우 인수 목록에서 유형을 구성 할 수 없습니다.

T t(declval<Args>()...);

잘 형성 하고 예외를 발생하지 알려진 . 복수 인수의 경우, 이것은 형식 변환 표현식형식 과 비공식에 해당합니다 (모듈러스 제외 제외, LWG 2116 참조 ).

T(declval<Args>()...)

그러나, 단일 인자 경우 표현은 T(declval<Args>())A와 취급 캐스팅 표현 호출 수 const_castreinterpret_cast ; 명시 적 사용은 static_cast선언 양식과 동등성을 복원합니다.

A와 구체적인 예를 들어 , 유형을 고려 :

struct D;
struct B { operator D&&() const; };
struct D : B {};

여기서 static_castfrom B constto D&&는 변환 연산자 를 사용해야하지만 캐스트 표현식은 변환 연산자를 무시할 수 있으므로 예외는 아닙니다. 따라서를 생략하면 static_cast잘못된 결과가 나타납니다 is_nothrow_constructible<D&&, B const>.


따라서 static_cast표현식이 항상 ? direct initialization대신 처리 되도록 cast expression? 가 필요합니다 .
João Pires

1
@ JoãoPires 네, 맞습니다. noexcept연산자를 사용하여 선언의 예외를 테스트 할 수는 없기 때문에 표준에 필요한 것은 여전히 ​​정확 하지는 않지만 훨씬 더 가깝습니다.
ecatmur

도와 주셔서 감사합니다! : D
João Pires
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.