¿Por qué se necesita static_cast en la implementación de gcc de is_nothrow_constructible?

11

Tomado de la implementación del CCG de type_traitspor qué se static_castnecesita aquí?

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>()))> {};
João Pires
fuente
Esa inconsistencia parece extraña
carreras de ligereza en órbita el
44
Debería hacer preguntas como esta en la lista de correo de libstdc ++ relevante
carreras ligeras en órbita el

Respuestas:

12

Un tipo no se puede construir a partir de una lista de argumentos si la declaración de variable inventada

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

estaría bien formado y se sabe que no arroja excepciones . En el caso del argumento plural, esto es equivalente (módulo sin excepción de la destructibilidad, ver LWG 2116 ) a la buena formabilidad y la no expresión de la expresión de conversión de tipo

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

Sin embargo, en el caso de argumento único, la expresión T(declval<Args>())se trata como una expresión de conversión , que puede invocar const_castyreinterpret_cast ; El uso explícito de static_castrestaura la equivalencia al formulario de declaración.

Como ejemplo concreto , considere los tipos:

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

Aquí, static_castfrom B constto D&&debe usar el operador de conversión, pero una expresión de conversión puede omitir el operador de conversión y, por lo tanto, no es excepto. Omitir el static_castdaría el resultado incorrecto is_nothrow_constructible<D&&, B const>.

ecatmur
fuente
Entonces, ¿ static_castse necesita para que la expresión siempre se trate como en direct initializationlugar de como cast expression?
João Pires
1
@ JoãoPires sí, es cierto. Todavía no es exactamente lo que exige el estándar porque no es posible probar sin excepción de una declaración con el noexceptoperador, pero está mucho más cerca.
ecatmur
¡gracias por la ayuda! : D
João Pires