Articulo de referencia

tipo decl

En el lenguaje de programación C++ , `decltype` (que significa "tipo declarado") es una palabra clave que se utiliza para consultar el tipo de una expresión . Introducida en C++...

Este es un buen artículo. Haz clic aquí para obtener más información.

En el lenguaje de programación C++ , `decltype` (que significa "tipo declarado") es una palabra clave que se utiliza para consultar el tipo de una expresión . Introducida en C++11 , su uso principal se da en la programación genérica , donde suele ser difícil, o incluso imposible, expresar tipos que dependen de parámetros de plantilla .

A medida que las técnicas de programación genérica se popularizaron durante la década de 1990, se reconoció la necesidad de un mecanismo de deducción de tipos. Muchos proveedores de compiladores implementaron sus propias versiones del operador, generalmente llamado `decltype` typeof, y se desarrollaron algunas implementaciones portátiles con funcionalidad limitada, basadas en características del lenguaje existentes. En 2002, Bjarne Stroustrup propuso que se añadiera una versión estandarizada del operador al lenguaje C++ y sugirió el nombre "decltype", para reflejar que el operador devolvería el "tipo declarado" de una expresión.

decltypeLa semántica de se diseñó para satisfacer tanto a los desarrolladores de bibliotecas genéricas como a los programadores novatos. En general, el tipo deducido coincide exactamente con el tipo del objeto o función tal como se declara en el código fuente . Al igual que el operador sizeof[ 1 ] , decltypeel operando de no se evalúa.

Una característica relacionada, el ^^operador (introducido en C++26 ), se utiliza para recuperar un valor de reflexión (metadatos de tipo) de cualquier símbolo. [ 2 ]

Motivación

Con la introducción de plantillas en el lenguaje de programación C++ y el advenimiento de las técnicas de programación genérica impulsadas por la Biblioteca de Plantillas Estándar , se reconoció la necesidad de un mecanismo para obtener el tipo de una expresión , comúnmente denominado typeof. En la programación genérica, a menudo es difícil o imposible expresar tipos que dependen de parámetros de plantilla, [ 3 ] [ 4 ] en particular el tipo de retorno de las instanciaciones de plantillas de función. [ 3 ]

Muchos proveedores ofrecen el typeofoperador como una extensión del compilador. [ 5 ] Ya en 1997, antes de que C++ estuviera completamente estandarizado, Brian Parker propuso una solución portátil basada en el sizeofoperador. [ 5 ] Su trabajo fue ampliado por Bill Gibbons, quien concluyó que la técnica tenía varias limitaciones y era generalmente menos potente que un typeofmecanismo real. [ 5 ] En un artículo de octubre de 2000 de Dr. Dobb's Journal , Andrei Alexandrescu comentó que "tener un typeof haría que mucho código de plantilla fuera más fácil de escribir y comprender". [ 6 ] También señaló que "typeof y sizeof comparten el mismo backend, porque sizeof tiene que calcular el tipo de todos modos". [ 6 ] Andrew Koenig y Barbara E. Moo también reconocieron la utilidad de una facilidad integrada typeof, con la salvedad de que "usarla a menudo invita a errores de programación sutiles, y hay algunos problemas que no puede resolver". [ 7 ] Caracterizaron el uso de convenciones de tipos, como los typedefs proporcionados por la Standard Template Library , como una técnica más potente y general. [ 7 ] Sin embargo, Steve Dewhurst argumentó que tales convenciones son "costosas de diseñar y promulgar", y que sería "mucho más fácil... simplemente extraer el tipo de la expresión". [ 8 ] En un artículo de 2011 sobre C++0x , Koenig y Moo predijeron que "decltype se utilizará ampliamente para facilitar la escritura de programas cotidianos". [ 9 ]

En 2002, Bjarne Stroustrup sugirió extender el lenguaje C++ con mecanismos para consultar el tipo de una expresión e inicializar objetos sin especificar el tipo. [ 3 ] Stroustrup observó que la semántica de eliminación de referencias ofrecida por el typeofoperador proporcionado por los compiladores GCC y EDG podría ser problemática. [ 3 ] Por el contrario, un operador que devolviera un tipo de referencia basado en la naturaleza lvalue de la expresión se consideró demasiado confuso. La propuesta inicial al comité de estándares de C++ describió una combinación de las dos variantes; el operador devolvería un tipo de referencia solo si el tipo declarado de la expresión incluía una referencia. Para enfatizar que el tipo deducido reflejaría el "tipo declarado" de la expresión, se propuso que el operador se denominara decltype. [ 3 ]

Una de las principales motivaciones citadas para la decltypepropuesta fue la capacidad de escribir plantillas de funciones de reenvío perfectas. [ 10 ] A veces es deseable escribir una función de reenvío genérica que devuelva el mismo tipo que la función encapsulada, independientemente del tipo con el que se instancie. Sin decltype, generalmente no es posible lograr esto. [ 10 ] Un ejemplo, que también utiliza el trailing-return-type : [ 10 ]

int & foo ( int & i ) { ++ i ; return i ; }float foo ( float & f ) { f += 1.0f ; return f ; }plantilla < clase T > auto forwarder ( T & t ) > decltype ( foo ( t )) { return foo ( t ); }

decltypees esencial aquí porque conserva la información sobre si la función encapsulada devuelve un tipo de referencia. [ 11 ]

Semántica

De forma similar al sizeofoperador, el operando de decltypeno se evalúa, por lo que expresiones como decltype(i++)no darán como resultado un incremento de la variable i. [ 12 ] De manera informal, el tipo devuelto por decltype(e)se deduce de la siguiente manera: [ 3 ]

  1. Si la expresión ese refiere a una variable en el ámbito local o de espacio de nombres, una variable miembro estática o un parámetro de función, entonces el resultado es el tipo declarado de esa variable o parámetro.
  2. De lo contrario, si ees un lvalue , decltype(e)es T&, donde Tes el tipo de e; si e es un xvalue , el resultado es T&&; de lo contrario, e es un prvalue y el resultado es T.
  3. Como caso especial, decltype(auto)permite la deducción de tipos como autopero conserva la categoría de valor del inicializador. Más específicamente, es equivalente a .decltype(initializer)

Estas semánticas fueron diseñadas para satisfacer las necesidades de los escritores de bibliotecas genéricas, al mismo tiempo que resultan intuitivas para los programadores novatos, ya que el tipo de retorno decltypesiempre coincide con el tipo del objeto o función exactamente como se declara en el código fuente. [ 3 ] Más formalmente, la Regla 1 se aplica a las expresiones de ID sin paréntesis y a las expresiones de acceso a miembros de clase. [ 13 ] [ 14 ] Ejemplo: [ 13 ] Nota para las líneas añadidas para bar(). Debajo del tipo deducido para "bar()" es int simple, no const int, porque los prvalues ​​de tipos que no son de clase siempre tienen tipos sin cualificación cv, a pesar del tipo diferente declarado estáticamente.

const int & foo () { static int val = 1 ; return val ; }const int bar () { return 1 ; }int i = 0 ;struct Double { double v ; };const Double * d = new Double ();decltype ( foo ()) x1 ; // el tipo es const int& decltype ( bar ()) x2 ; // el tipo es int decltype ( i ) x3 ; // el tipo es int decltype ( d -> i ) x4 ; // el tipo es double decltype (( d -> i )) x5 ; // el tipo es const double&eliminar d ;

La razón de la diferencia entre las dos últimas invocaciones de decltypees que la expresión entre paréntesis (a->x)no es ni una expresión de ID ni una expresión de acceso a miembros, y por lo tanto no denota un objeto con nombre. [ 15 ] Debido a que la expresión es un lvalue, su tipo deducido es "referencia al tipo de la expresión", o const double&. [ 12 ] El hecho de que los paréntesis adicionales introduzcan un calificador de referencia al tipo puede ser una fuente de errores para los programadores que no comprenden completamente decltype. [ 16 ]

En diciembre de 2008, Jaakko Järvi planteó al comité una preocupación sobre la incapacidad de usarlo decltypepara formar un identificador calificado , [ 1 ] lo cual es inconsistente con la intención de que decltype(e)se trate "como si fuera un nombre de tipo definido ". [ 17 ] Al comentar sobre el borrador formal del Comité para C++0x , el organismo miembro japonés de la ISO señaló que "un operador de ámbito (::) no se puede aplicar a decltype, pero debería. Sería útil en el caso de obtener el tipo de miembro (tipo anidado) de una instancia de la siguiente manera: [ 18 ]

vector < int > v ; decltype ( v ) :: value_type i = 0 ; // int i = 0;

Este y otros problemas similares relacionados con la redacción que inhibe el uso de decltypeen la declaración de una clase derivada y en una llamada a un destructor , fueron abordados por David Vandevoorde y votados en el documento de trabajo en marzo de 2010. [ 19 ] [ 20 ]

Disponibilidad

decltypeestá incluido en el estándar del lenguaje C++ desde C++11 . [ 13 ] Varios compiladores lo proporcionan como una extensión. Los compiladores Visual C++ 2010 y posteriores de Microsoft proporcionan un especificador de tipo que imita fielmente la semántica descrita en la propuesta del comité de estándares. Puede utilizarse tanto con código administrado como nativo. [ 11 ] La documentación indica que es "útil principalmente para desarrolladores que escriben bibliotecas de plantillas". [ 11 ] se añadió a la rama principal del compilador GCC C++ en la versión 4.3, [ 21 ] publicada el 5 de marzo de 2008. [ 22 ] también está presente en C++ Builder 2009 de Codegear , [ 23 ] el compilador Intel C++ , [ 24 ] y Clang . [ 25 ]decltypedecltypedecltype

Referencias

  1. 1 2 Miller, William M. (2009-09-29). "C++ Standard Core Language Active Issues, Revision 66" . ISO/IEC JTC1/SC22/WG21 – The C++ Standards Committee . Recuperado el 2009-10-03 .
  2. Wyatt Childers; et al. (26 de junio de 2024). "P2996R4 - Reflexión para C++26" . isocpp.org . WG21. 
  3. 1 2 3 4 5 6 7 Gregor, Douglas; Järvi, Jaakko; Siek, Jeremy; Stroustrup, Bjarne (28 de abril de 2003). "Decltype y auto" (PDF) . ISO/IEC JTC1/SC22/WG21 – El Comité de Normas C++ . Consultado el 28 de agosto de 2015 .
  4. Kalev, Danny (2008-05-08). "Limpiar el desorden de sintaxis de funciones con decltype " . DevX.com . Recuperado el 2009-09-04 .
  5. 1 2 3 Gibbons, Bill (2000-11-01). "Un operador portátil de "tipo" tipo" . Dr. Dobb's Journal . Recuperado el 2009-09-03 .
  6. 1 2 Alexandrescu, Andrei (2000-10-01). "Generic<Programming>: Mappings between Types and Values" . Dr. Dobb's Journal . Recuperado el 2009-09-03 .
  7. 1 2 Koenig, Andrew; Barbara E. Moo (2002-02-01). "C++ Made Easier: Naming Unknown Types" . Dr. Dobb's Journal . Recuperado el 2009-09-03 .
  8. Dewhurst, Steve (1 de agosto de 2000). "Conocimiento común: un operador bit a bit, parte 1" . Dr. Dobb's Journal . Recuperado el 3 de septiembre de 2009 .
  9. Koenig, Andrew; Barbara E. Moo (19 de julio de 2011). "4 nuevas características útiles en C++0x" . Dr. Dobb's Journal . Recuperado el 12 de enero de 2012 .
  10. 1 2 3 Dos Reyes, Gabriel; Järvi, Jaakko; Stroustrup, Bjarne (12 de octubre de 2004). "Decltype y auto (revisión 4)" (PDF) . ISO/IEC JTC1/SC22/WG21 – El Comité de Normas C++ . Consultado el 4 de septiembre de 2009 .
  11. 1 2 3 "decltype Operator" . Microsoft Corporation . Consultado el 4 de septiembre de 2009 .
  12. 1 2 Dos Reis, Gabriel; Järvi, Jaakko; Stroustrup, Bjarne (18 de julio de 2007). "Decltype (revisión 7): redacción propuesta" (PDF) . ISO/IEC JTC1/SC22/WG21 – El Comité de Normas C++ . Consultado el 4 de septiembre de 2009 .
  13. 1 2 3 Becker, Pete. "Borrador de trabajo, estándar para el lenguaje de programación C++" (PDF) . ISO/IEC JTC1/SC22/WG21 – Comité de estándares de C++ . Recuperado el 4 de septiembre de 2009 .
  14. Miller, William M. (3 de agosto de 2009). "Informes de defectos del lenguaje central estándar de C++, revisión 65" . ISO/IEC JTC1/SC22/WG21 – Comité de estándares de C++ . Recuperado el 15 de septiembre de 2009 .
  15. Miller, William M. (3 de agosto de 2009). "Problemas cerrados del lenguaje central estándar de C++, revisión 65" . ISO/IEC JTC1/SC22/WG21 – Comité de estándares de C++ . Recuperado el 4 de septiembre de 2009 .
  16. Mazières, David (junio de 2021). "Categorías de valores y decltype de C++ desmitificados" . Recuperado el 16 de junio de 2022 .
  17. Dos Reyes, Gabriel; Järvi, Jaakko; Stroustrup, Bjarne (5 de noviembre de 2006). "Decltype (revisión 6): redacción propuesta" (PDF) . ISO/IEC JTC1/SC22/WG21 – El Comité de Normas C++ . Consultado el 3 de octubre de 2009 .
  18. Miller, William M. (2009-08-03). "Estado de los comentarios de C++ CD1" . ISO/IEC JTC1/SC22/WG21 – Comité de estándares de C++ . Recuperado el 2009-10-03 .
  19. Miller, William M. (29 de marzo de 2010). "Informes de defectos del lenguaje central estándar de C++, revisión 69" . ISO/IEC JTC1/SC22/WG21 – Comité de estándares de C++ . Recuperado el 10 de abril de 2010 .
  20. Vandevoorde, Daveed (2010-02-03). "Problemas centrales 743 y 950: Usos adicionales de decltype(...)" (PDF) . ISO/IEC JTC1/SC22/WG21 – Comité de Estándares de C++ . Recuperado el 10 de abril de 2010 .
  21. "Soporte para C++0x en GCC" . Free Software Foundation . 27 de agosto de 2009. Consultado el 4 de septiembre de 2009 .
  22. "Serie de lanzamientos de GCC 4.3" . Free Software Foundation . 13 de agosto de 2009. Consultado el 4 de septiembre de 2009 .
  23. "Especificador de tipo decltype (C++0x)" . Embarcadero Technologies. Archivado del original el 8 de julio de 2011. Consultado el 4 de septiembre de 2009 .
  24. "std, Qstd" . Intel Corporation . Consultado el 4 de septiembre de 2009 .
  25. Gregor, Douglas (26 de enero de 2011). "Nuevo soporte para características C++0x en Clang" . Archivado del original el 30 de enero de 2011.
  • Entrada de Bjarne Stroustrup en las preguntas frecuentes sobre C++0x para decltype