verbos uso tipos resueltos resuelto plantilla para hacer flujo especificacion ejercicios ejemplos ejemplo diagrama detallado como casos caso alternativo c++ c++11 language-lawyer

c++ - resueltos - tipos de casos de uso



Casos de uso para std:: add_const y similares (4)

El único caso de uso que conozco se ilustra a continuación:

struct F { bool f() const { return true; } bool f() { return false; } }; assert(!F{}.f()) assert(std::add_const_t< F >{}.f());

También se necesita para probar la funcionalidad de funciones miembro calificadas para cv-ref , que puede diferir para diferentes sobrecargas (solo para C ++ moderno calificado como std::as_const función std::as_const útil):

struct F { int g() & { return 1; } int g() const & { return 2; } int g() && { return 3; } int g() const && { return 4; } }; F f; assert(f.g() == 1); assert(std::as_const(f).g() == 2); assert(F{}.g() == 3); assert(std::add_const_t< F >{}.g() == 4); // rarely needed, but if needed, then it helps

Algunas transformaciones de tipo en <type_traits> también pueden expresarse usando la sintaxis del lenguaje central (por ejemplo, std::add_const<T>::type es equivalente a const T ). Dtto para std::add_lvalue_reference , y quizás otros. ¿Cuál es el uso de estos rasgos de tipo?

Entiendo completamente que el estándar proporcionaría una "caja de herramientas incompleta" sin ellos, y puedo imaginar su uso de forma meta, algo como esto:

template<typename In, template <typename> class Modifier> struct Apply { typedef typename Modifier<T>::type Out; }; Apply<int, std::add_const>

¿Hay otros casos de uso para estos rasgos que puedan expresarse de manera sintáctica, o simplemente se incluyen "por un sentido de integridad" y para el uso ocasional de meta?


Esos rasgos provienen de Boost y la propuesta de agregarlos al estándar, N1345 , cita a Andrei Alexandrescu diciendo:

"Entiendo el argumento de simetría para agregar add_const , add_volatile , add_cv y add_pointer , sin embargo, argumentaría a favor de eliminarlos. Los equivalentes proporcionados por el lenguaje son simplemente más simples y agradables".

La misma propuesta también da esta justificación:

Nota del autor: superficialmente las clases add_const, add_volatile y add_cv son irrelevantes, ya que, por ejemplo, add_const :: type es lo mismo que T const, para todas las T (actualmente esto no se aplica a los tipos de función, pero el problema 295 lo soluciona). Sin embargo, la experiencia de impulso es que varios usuarios han pedido que estas plantillas estén presentes en la biblioteca por las siguientes razones: (a) Algunos usuarios encuentran estas más explícitas: al combinar plantillas de transformación en particular, a los usuarios les gusta el tipo de "incorporado". documentación "que proporcionan estas plantillas. (b) No todos los usuarios son conscientes de que una referencia que califica para cv está permitida y no tiene ningún efecto, o que un tipo que ya está calificado para cv está permitida y no tiene ningún efecto. (c) Los compiladores pueden emitir advertencias cuando califican para cv un tipo que es una referencia, o ya tienen un calificador de cv, estas plantillas pueden implementarse de manera que estos mensajes se supriman en estos casos.

Además, para add_reference (renombrado a add_lvalue_reference en el estándar):

Nota del autor: la plantilla add_reference fue una de las motivaciones originales detrás de la biblioteca de rasgos de tipo boost. Sin embargo, la resolución para emitir 106 hace que la plantilla parezca en gran parte redundante. A pesar de que add_reference puede ser útil para suprimir las advertencias del compilador cuando se crean inadvertidamente referencias a referencias en el código de la plantilla.


Estos rasgos se proporcionan para el uso meta ocasional. Posibilita el transporte de calificadores cv deseados alrededor de la meta programación.

template<class T,template<class> class Trait> struct transform { /* working with T creating newT*/ typedef Trait<newT>::type type; }; template<class T> struct special_transform : transfrom<T, std::add_const> {};

En este caso no podría reemplazar std::add_const con const .


add_const se puede utilizar para resolver conflictos de deducción de tipo.

template <typename T> class wrapper; template <typename T> bool operator==(wrapper<T> const& w, T const& t);

Los problemas surgen si usamos wrapper<T const> :

wrapper<int const> w = { 42 }; assert(w == 42); // Error: conflicting deduced types

T se deduce simultáneamente como int y int const . Esto se puede resolver usando add_const :

template <typename T> bool operator==(wrapper<T> const& w, add_const_t<T>& t);