stringtranslate.com

tipo de decl

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

A medida que las técnicas de programación genérica se hicieron cada vez más populares a lo largo de 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 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 agregara una versión estandarizada del operador al lenguaje C++ y sugirió el nombre "decltype", para reflejar que el operador produciría el "tipo declarado" de una expresión.

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

Motivación

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

Muchos proveedores proporcionan el typeofoperador como una extensión del compilador. [4] Ya en 1997, antes de que C++ estuviera completamente estandarizado, Brian Parker propuso una solución portátil basada en el sizeofoperador. [4] Su trabajo fue ampliado por Bill Gibbons, quien concluyó que la técnica tenía varias limitaciones y era generalmente menos poderosa que un typeofmecanismo real. [4] En un artículo de octubre de 2000 del 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 entender". [5] También señaló que "typeof y sizeof comparten el mismo backend, porque sizeof tiene que calcular el tipo de todos modos". [5] Andrew Koenig y Barbara E. Moo también reconocieron la utilidad de una función incorporada typeof, con la salvedad de que "usarla a menudo invita a errores de programación sutiles, y hay algunos problemas que no puede resolver". [6] Caracterizaron el uso de convenciones de tipos, como las typedefs proporcionadas por la Biblioteca de plantillas estándar , como una técnica más poderosa y general. [6] 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". [7] En un artículo de 2011 sobre C++0x , Koenig y Moo predijeron que "decltype se usará ampliamente para hacer que los programas cotidianos sean más fáciles de escribir". [8]

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. [2] 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. [2] 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 llamara decltype. [2]

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

int & foo ( int & i ); flotador foo ( flotador & f );    plantilla < clase T > auto transparent_forwarder ( T & t ) > decltype ( foo ( t )) { return foo ( t ); }          

decltypees esencial aquí porque preserva la información sobre si la función envuelta devuelve un tipo de referencia. [10]

Semántica

De manera 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. [11] De manera informal, el tipo devuelto por decltype(e)se deduce de la siguiente manera: [2]

  1. Si la expresión se 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 declaradoe 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 tipo como , autopero conserva la categoría del 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, mientras que al mismo tiempo son intuitivas para programadores novatos, porque el tipo de retorno de decltypesiempre coincide con el tipo del objeto o función exactamente como se declara en el código fuente. [2] Más formalmente, la Regla 1 se aplica a expresiones id sin paréntesis y expresiones de acceso a miembros de clase. [12] [13] Ejemplo: [12] Nota para líneas agregadas para bar(). A continuación, el tipo deducido para "bar()" es int simple, no int constante, porque los prvalues ​​de tipos que no son de clase siempre tienen tipos cv-no calificados, a pesar del tipo diferente declarado estáticamente.

const int && foo (); const int bar (); int i ; struct A { double x ; }; const A * a = new A (); decltype ( foo ()) x1 ; // el tipo es const int&& decltype ( bar ()) x2 ; // el tipo es int decltype ( i ) x3 ; // el tipo es int decltype ( a -> x ) x4 ; // el tipo es double decltype (( a -> x )) x5 ; // el tipo es const double&                         

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 id ni una expresión de acceso a miembros y, por lo tanto, no denota un objeto nombrado. [14] Debido a que la expresión es un valor l, su tipo deducido es "referencia al tipo de la expresión", o const double&. [11] 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. [15]

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

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

David Vandevoorde abordó 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 al destructor y los votó para incluirlos en el documento de trabajo en marzo de 2010. [18] [19]

Disponibilidad

decltypese incluye en el estándar del lenguaje C++ desde C++11 . [12] Es proporcionado por varios compiladores como una extensión. Los compiladores Visual C++ 2010 y posteriores de Microsoft proporcionan un especificador de tipo que imita de cerca la semántica descrita en la propuesta del comité de estándares. Se puede utilizar tanto con código administrado como nativo. [10] La documentación afirma que es "útil principalmente para desarrolladores que escriben bibliotecas de plantillas". [10] se agregó a la línea principal del compilador GCC C++ en la versión 4.3, [20] publicada el 5 de marzo de 2008. [21] también está presente en C++ Builder 2009 de Codegear , [22] el compilador Intel C++ , [23] y Clang . [24]decltype decltype decltype

Referencias

  1. ^ ab Miller, William M. (29 de septiembre de 2009). "Problemas activos del lenguaje básico estándar C++, revisión 66". ISO/IEC JTC1/SC22/WG21 – Comité de estándares C++ . Consultado el 3 de octubre de 2009 .
  2. ^ abcdefg 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 .
  3. ^ Kalev, Danny (8 de mayo de 2008). "Limpiar la sintaxis de funciones con decltype". DevX.com . Consultado el 4 de septiembre de 2009 .
  4. ^ abc Gibbons, Bill (1 de noviembre de 2000). "Un operador portátil tipo "of". Diario del Dr. Dobb . Consultado el 3 de septiembre de 2009 .
  5. ^ ab Alexandrescu, Andrei (1 de octubre de 2000). "Programación genérica: asignaciones entre tipos y valores". Diario del Dr. Dobb . Consultado el 3 de septiembre de 2009 .
  6. ^ ab Koenig, Andrew; Barbara E. Moo (1 de febrero de 2002). "C++ simplificado: nombrar tipos desconocidos". Diario del Dr. Dobb . Consultado el 3 de septiembre de 2009 .
  7. ^ Dewhurst, Steve (1 de agosto de 2000). "Conocimiento común: un operador bit a bit typeof, parte 1". Diario del Dr. Dobb . Consultado el 3 de septiembre de 2009 .
  8. ^ Koenig, Andrew; Barbara E. Moo (19 de julio de 2011). "4 nuevas características útiles en C++0x". Diario del Dr. Dobb . Consultado el 12 de enero de 2012 .
  9. ^ abcDos Reis, 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 .
  10. ^ abc "Operador decltype". Microsoft Corporation . Consultado el 4 de septiembre de 2009 .
  11. ^ ab 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 .
  12. ^ abc 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++ . Consultado el 4 de septiembre de 2009 .
  13. ^ Miller, William M. (3 de agosto de 2009). "Informes de defectos del lenguaje básico estándar C++, revisión 65". ISO/IEC JTC1/SC22/WG21 – Comité de estándares C++ . Consultado el 15 de septiembre de 2009 .
  14. ^ Miller, William M. (3 de agosto de 2009). "Problemas cerrados del lenguaje básico estándar C++, revisión 65". ISO/IEC JTC1/SC22/WG21 – Comité de estándares C++ . Consultado el 4 de septiembre de 2009 .
  15. ^ Mazières, David (junio de 2021). «Desmitificación de las categorías de valores y decltype de C++» . Consultado el 16 de junio de 2022 .
  16. ^ 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 .
  17. ^ Miller, William M. (3 de agosto de 2009). "Estado de los comentarios sobre el CD1 de C++". ISO/IEC JTC1/SC22/WG21 – Comité de estándares de C++ . Consultado el 3 de octubre de 2009 .
  18. ^ Miller, William M. (29 de marzo de 2010). "Informes de defectos del lenguaje básico estándar C++, revisión 69". ISO/IEC JTC1/SC22/WG21 – Comité de estándares C++ . Consultado el 10 de abril de 2010 .
  19. ^ Vandevoorde, Daveed (3 de febrero de 2010). "Problemas básicos 743 y 950: usos adicionales de decltype(...)" (PDF) . ISO/IEC JTC1/SC22/WG21 – Comité de estándares de C++ . Consultado el 10 de abril de 2010 .
  20. ^ "Compatibilidad con C++0x en GCC". Free Software Foundation . 2009-08-27 . Consultado el 2009-09-04 .
  21. ^ "Serie de versiones GCC 4.3". Free Software Foundation . 13 de agosto de 2009. Consultado el 4 de septiembre de 2009 .
  22. ^ "Especificador de tipo decltype (C++0x)". Embarcadero Technologies. Archivado desde el original el 8 de julio de 2011. Consultado el 4 de septiembre de 2009 .
  23. ^ "std, Qstd". Intel Corporation . Consultado el 4 de septiembre de 2009 .
  24. ^ Gregor, Douglas (26 de enero de 2011). "Compatibilidad con nuevas funciones de C++0x en Clang". Archivado desde el original el 30 de enero de 2011.

Enlaces externos