C++17 permite escribir código simple, más claro y más expresivo. Algunas de las características introducidas en C++17 son:
- Espacios de nombres anidados
- Declaración de variables en if y switch
- si declaración constexpr
- Encuadernaciones estructuradas
- Expresiones de pliegue
- Inicialización de lista directa de enumeraciones
Con la nueva versión de C++17, se introducen muchas funciones nuevas, pero algunas características se eliminan o quedan obsoletas. Estos se enumeran a continuación:
- Eliminación del operador obsoleto ++
- Eliminación de registros
- Eliminación de auto_ptr
- trigrafos
- tirar (typeid)
- Soporte de asignador en std::function
- std::pointer_to_unary_function y std::pointer_to_binary_function
- std::binder1st y std::binder2nd
- std::bind1st y std::bind2nd
- Otras funciones.
Comencemos discutiendo estas funciones en detalle.
1. Eliminación del operador obsoleto ++: las expresiones Postfix y Prefix Increment (++) ahora no son válidas para los operandos bool , ya que el prefijo y el postfix operator++ estaban sobrecargados para el tipo bool, pero en ambos casos, el valor de retorno para un argumento bool es verdad. El tipo bool no admite el conjunto completo de tipos aritméticos. Desde el lanzamiento de C++98 , se ha esperado este cambio. En la nueva versión de C++17, ya no se considera un tipo aritmético y estos operadores han quedado obsoletos.
Alternativas: el std::exchange se puede usar como una alternativa para esto, pero solo donde el operador postfix tiene usos válidos. La función de intercambio reemplaza el valor del objeto con un valor nuevo y devuelve el valor anterior del objeto.
2. Eliminación de registros: hace mucho tiempo, en C++ 11 , la palabra clave de registro estaba en desuso. La palabra clave de registro especifica o le da una pista al compilador de que la variable se puede colocar en un registro para un acceso rápido o que estas variables se pueden usar mucho para que pueda optimizarlas almacenándolas en un registro de la CPU. Pero los compiladores realizan optimizaciones implícitas y la sugerencia rara vez se usaba. Por lo tanto, en la nueva versión se elimina la palabra clave registro, aunque la palabra clave sigue reservada para futuras versiones.
Sintaxis:
register string s = "Register on GfG"
Alternativas: No hay alternativa para registrarse ya que el compilador hace el mismo trabajo automáticamente.
3. Eliminación de auto_ptr: auto_ptr se usó para crear un puntero inteligente para manejar la vida útil de un objeto . Es el propietario del objeto al que se refiere. Cuando se destruye un objeto, auto_ptr también se destruye automáticamente. Este puntero inteligente roba silenciosamente la propiedad del objeto administrado en su constructor de copia y la asignación de copia del argumento de la derecha. Como resultado, la copia no es igual que el objeto de puntero inteligente original. Debido a esta semántica de copia, auto_ptr no funciona como CopyConstructible y, por lo tanto, está en desuso.
Alternativas: el auto_ptr se puede reemplazar fácilmente por unique_ptr , que también es un puntero inteligente con un trabajo similar pero con seguridad mejorada. Se introdujo en C++ 11 como reemplazo directo de auto_ptr , ya que proporciona nuevas funciones (eliminaciones) y soporte para arreglos. Además, solo permite un propietario del puntero de referencia. Por lo tanto, al usar unique_ptr , solo puede haber como máximo un unique_ptr para un recurso y cuando se destruye, el recurso se reclama automáticamente. Si se intenta hacer una copia de unique_ptr , se producirá un error en tiempo de compilación .
Ejemplo:
unique_ptr<T> p1 (new T); unique_ptr<T> p2 = p1; // Error: can't copy unique_ptr
4. Trigraphs: Los Trigraphs son un grupo de tres caracteres . Básicamente, es una secuencia de caracteres especial que se utiliza como alternativa para algunos caracteres. Se representa con dos signos de interrogación.
Ejemplo:
??- produces ~ ??= produces # ??/ produces \ ??’ produces ^ ??( produces [ ??) produces ] ??! produces | ??< produces { ??> produces }
Pero producen mucha confusión ya que se analizan antes de los comentarios y, por lo tanto, se eliminan en la última versión.
Alternativas: C++17 no ofrece ninguna alternativa para Trigraph, ya que los teclados modernos tienen todas estas características. Además, produce muchos errores en el código.
5. throw(typeid): si se declara alguna función con el tipo T enumerado en su especificación de excepción, la función puede generar excepciones a ese tipo oa un tipo derivado de él. Esta es la versión que no lanza de la especificación de excepción dinámica que ha quedado en desuso y ahora se eliminó. Ha sido reemplazado por noexcept que tiene un significado más claro.
Sintaxis:
throw(typeid, typeid, ...)
Ejemplo:
void throwsInt(int x) throw(int) { cout<<"throw function replaced with noexcept :)"; if (x == 0) { throw 1; } }
Alternativas: como se mencionó anteriormente, throw puede tener una mejor alternativa con noexcept . Especifica si las funciones pueden lanzar excepciones o no sin especificar su tipo. Pero úselo solo cuando la invocación de la función no pueda arrojar ningún error, de lo contrario, el programa terminará.
6. Soporte de asignador en std::function: varios constructores permiten especificar un asignador utilizado para asignar memoria interna. std::function también tiene constructores que toman un argumento de asignador, pero la semántica no está clara y hay fallas técnicas al almacenar un asignador en un contexto de tipo borrado y luego recuperar ese asignador más tarde para cualquier asignación necesaria durante la asignación de copia. Por lo tanto, estas sobrecargas de constructores se eliminaron en C++17.
Alternativas: dicha función no está presente en C++ , que reemplaza al asignador.
7. std::pointer_to_unary_function, std::pointer_to_binary_function: std::pointer_to_unary_function , std::pointer_to_binary_function objetos de función que actúan como envoltorios de funciones unarias o binarias. Estas funciones incluyen un constructor que construye un nuevo objeto pointer_to_unary_function con la función proporcionada y la función operator() que llama a la función almacenada.
Alternativas: estas dos funciones std::function y std::ref reemplazan std::pointer_to_unary_function , std::pointer_to_binary_function .
8. std::binder1st y std::binder2nd: estos son objetos de función que vinculan un argumento a una función binaria. El valor del parámetro se pasa al objeto en el momento de la construcción y se almacena dentro del objeto. Cada vez que se invoca el objeto de función a través de la función operator() , el valor almacenado se pasa como uno de los argumentos, el otro argumento se pasa como un argumento de operator(). El objeto de función resultante es una función unaria.
- binder1st: Vincula el primer parámetro al valor dado en el momento de la construcción del objeto.
- binder2nd: Vincula el segundo parámetro al valor dado en el momento de la construcción del objeto.
Alternativas: Lambdas , std::bind son dos características que pueden ser alternativas para binder1st y binder2nd.
9. std::bind1st y std::bind2nd: estas son funciones auxiliares que crean instancias de std::bind1st o std::bind2nd, que vincula un argumento dado a un primer o segundo parámetro de un objeto de función binaria dado. Pero estos no sirven con la introducción de lambdasin C++11, por lo tanto, quedaron en desuso.
10. Otras funciones:
- estándar::mem_fun_t,
- estándar::mem_fun1_t
- estándar::const_mem_fun_t
- estándar::const_mem_fun1_t
- estándar::mem_fun_ref_t
- estándar::mem_fun1_ref_t
- estándar::const_mem_fun_ref_t
- estándar::const_mem_fun1_ref_t
Estos son objetos de función que envuelven un puntero a una función miembro sin parámetros o con un parámetro. La instancia de clase cuya función miembro para llamar se pasa como un puntero al operador(), es decir, el objeto cuya función miembro para llamar se pasa por el puntero al operador de llamada para este último, se pasa como una referencia. Están en desuso porque están limitados a funciones miembro con ninguno o solo un argumento y se requieren diferentes funciones y objetos de función para manejar punteros o referencias a la instancia de clase.
Alternativas: la alternativa a las funciones anteriores es std::mem_fn , que puede manejar funciones miembro con cualquier cantidad de variables y no solo referencias o punteros a objetos, sino también punteros inteligentes.
Publicación traducida automáticamente
Artículo escrito por animeshmaru16 y traducido por Barcelona Geeks. The original can be accessed here. Licence: CCBY-SA