C++17

La versión actual de la página aún no ha sido revisada por colaboradores experimentados y puede diferir significativamente de la versión revisada el 5 de mayo de 2021; las comprobaciones requieren 17 ediciones .

C++17 (también conocido como C++1z) es el nombre de la versión ISO /IEC del estándar C++. Las especificaciones para C++17 se publicaron en diciembre de 2017 [1] [2] .

El valor de la constante __cplusplusse ha convertido en 201703L, esto se usa para la compilación condicional .

Eliminado o prohibido

Trigrafos eliminados

Los trígrafos se utilizaron para máquinas con codificación no estándar y/o teclados limitados. A finales de los años 80, con la difusión de las codificaciones de 8 bits y los teclados de membrana de caucho baratos , los trigrafos perdieron su significado, y treinta años más tarde fueron naturalmente excluidos [3] [4] .

// ¿Se ejecutará la siguiente línea????????????????/ a ++ ; /* con trigraphs esta línea está comentada - trigraph ??/ es equivalente a \ */

Se eliminó la palabra clave de registro

El lenguaje C era un "ensamblador portátil": permitía hacer programas rápidos que se compilaban en diferentes computadoras, y también usaba utilidades de ensamblador ( enlazador , bibliotecario). Conceptos como " archivo de cabecera " y " unidad de traducción " son ecos de aquellos tiempos.

La palabra registerse asoció originalmente con la optimización manual del programa. Los compiladores modernos "debajo del capó" realizan una gran cantidad de optimizaciones, y ese control manual parece redundante. En C++ 11, la palabra se declaró indeseable. La palabra aún está reservada y es posible que algún día se use para un propósito diferente, como en C++11 [5] . auto

Se eliminó la operación ++ para bool

La operación obviamente no es segura y está prohibida en C++98 [6] . --Falta la operación .

Excepciones declaradas eliminadas

Las excepciones declaradas void f() throw(A, B, C);, que se encuentran en Java , por ejemplo, hacen más daño que bien. Prohibido en C++11, eliminado en C++17. Permaneció throw()como sinónimo de noexcept(true)[7] .

Se eliminaron tipos y funciones que fueron reemplazados (y prohibidos) en C++ 11

Entre ellos se encuentran std::auto_ptrantiguos std::random_shuffleadaptadores funcionales [8] [9] .

En su lugar, unique_ptrse utilizan shuffley nuevas plantillas de funciones basadas en function/ bind. Se afirma que cualquier código en auto_ptrse puede convertir mecánicamente a unique_ptr, con una simple adición std::movedonde hay una transferencia de propiedad.

También se han eliminado partes separadas iostreamprohibidas en C++98 [10] .

Se eliminaron los constructores para std::function que tomaba un asignador

Cinco sobrecargas en total, incluida esta.

plantilla < classAlloc > _ function ( std :: allocator_arg_t , const Alloc & alloc ) noexcept ;

Debido a la semántica incomprensible y las dificultades de implementación, se eliminaron sin prohibición previa [11] .

Las características extremadamente raras de la biblioteca estándar están prohibidas

Varias características raras de la biblioteca estándar están prohibidas: [12] [13] [14]

  • allocator<void> - resultó no ser reclamado;
  • algunas de las funciones allocator están duplicadas por la plantilla allocator_traits;
  • raw_storage_iterator - no llama a los constructores y, por lo tanto, tiene una aplicación limitada;
  • get_temporary_buffer - tiene trampas no obvias;
  • is_literal_type - inútil para código genérico, pero se deja siempre que haya un concepto de "tipo literal" en C++;
  • iterator - es más fácil escribir iteradores desde cero que construir sobre ellos;
  • codecvt - de hecho, funcionó muy mal, el comité pidió el uso de bibliotecas especializadas;
  • shared_ptr::unique() - debido a la falta de fiabilidad en un entorno de subprocesos múltiples.

Prometen eliminarlos por completo en C++20.

Prohibiciones relacionadas con las nuevas funciones de C++17

  • result_of→ invoke_resultes una sintaxis más simple basada en la inferencia de tipo C++11 [15] ;
  • bool uncaught_exception()→ int uncaught_exceptions() - en el procesamiento de una excepción, el sistema puede lanzar otra, por lo que varias excepciones pueden "colgarse" sin manejar. Verificar cuántos de ellos estaban en el constructor y cuántos en el destructor es un método más confiable y "gratuito" desde el punto de vista de las bibliotecas disponibles para determinar si lanzar o no una excepción desde el destructor [16] [ 17] [18] .

Se eliminaron los encabezados de la biblioteca C

Con la transición a C11, los archivos de encabezado <ccomplex>, <cstdalign>, <cstdbool>, <ctgmath>. El archivo <ciso646>no está prohibido [19] .

autox{}; ya no crea una initializer_list

El inicializador universal agregado en C ++ 11 int x{};le permite crear un objeto, estructura, matriz con una sintaxis. En C++17, se aclara: si en lugar de un tipo se encuentra , el autousuario quiere crear un objeto y no se necesita initializer_list.

Al mismo tiempo , auto x = {1, 2, 3};continúa creando: por un lado, por compatibilidad con , por otro lado, hay [20] [9]for (auto x : {1, 2, 3}) para un objeto . auto x = 1;

automático x1 = { 3 }; // std::initializer_list<int> auto x2 { 1 , 2 }; // error ahora auto x3 { 3 }; // En t

Cambios Globales

La especificación de excepción ahora es parte del sistema de tipos

Las funciones y  ahora son funciones con diferentes tipos (pero no pueden formar un conjunto sobrecargado). Esto permitirá que la API solicite devoluciones de llamada que no generen excepciones, así como optimizar el código para none [21] . void f() noexcept(true);void f() noexcept(false);

Nuevo sobrealineado

C++11 introdujo la capacidad de crear estructuras de datos cuya alineación es mayor que la teórica. Esta posibilidad fue recogida por la nueva operación [22] .

clase alinea ( 16 ) float4 { flotante f [ 4 ]; }; float4 * p = nuevo float4 [ 1000 ];

Hubo una sobrecarga del operador new con un parámetro adicional para asignar correctamente un objeto sobrealineado en la memoria.

Eliminación obligatoria de copias

Se ha cambiado el significado del concepto prvalue: ahora es solo una inicialización.

Si bien el código SomeType a = 10;aún requiere tanto el constructor como el operador =, solo se garantiza que se llamará al constructor.

Esto significa que las funciones pueden devolver tipos que no se pueden copiar ni mover.

Orden de evaluación más estricto

Ahora las operaciones a.b, a->b, a->*b, a(b1, b2, b3), b += a(y análogos para otras operaciones), a[b], a << by a >> bse evalúan en el orden a → b para mantener los efectos secundarios bajo control [23] .

Si se llaman como funciones (por ejemplo, operator += (a, b)), el orden permanece indefinido.

Se amplió el concepto de "constante en la plantilla"

Hay plantillas que aceptan una constante.

plantilla < int N > estructura Matriz { int a [ N ]; };

Lo que puede ser una N constante, y lo que no puede - declarado lo contrario. Una constante en una plantilla no puede ser un puntero a un campo, un objeto temporal, un literal de cadena, un resultado typeido una variable estándar __func__[17] [24] ;

Porque puede tener inicio y final de diferentes tipos

Now for (auto v : x)significa , permitiendo inicio y fin de diferentes tipos. auto __begin = begin-expr; auto __end = end-expr;

Esta es la base para iterar a través de los rangos, que es un trabajo en progreso [25] .

Cambios editoriales

El concepto de un "iterador continuo"

Las matrices std::vector y std::string se ocupan de las regiones contiguas de la memoria. Introdujeron el concepto de "iterador continuo" [26] [27] . Conceptualmente, nada ha cambiado.

También dieron definiciones a otros conceptos: referencia de reenvío , inicializador de miembro predeterminado , entidad con plantilla . Este es un trabajo sobre conceptos de C++20 .

Los caracteres u'x' y U'x' que no estén codificados por un solo carácter están prohibidos

Anteriormente, este comportamiento estaba definido por la implementación.

Al mismo tiempo, crearon "caracteres UTF-8" que tienen un tipo y pueden contener códigos del 0 al 127, similares a las cadenas UTF-8, aparentemente, para que el programa dependa menos de la configuración regional de la computadora [ 17] [28] . char

Deshabilitado temporalmente memory_order_consume

Debido a una semántica inadecuada, se prohibió verbalmente (sin la marca ) el método de pedido “consumir” , exigiendo el uso del método “adquirir”. El trabajo sobre la nueva semántica aún está en curso, y tal vez algún día se levante la prohibición [29] . [[deprecated]]

En cualquier caso, en PowerPC y ARM , todas las descargas consumirán automáticamente , pero no todas adquirirán , y el método de consumo puede ahorrar relojes en código multiplataforma [30] .

Idioma

static_assert con un argumento

Si static_assertno funciona, no siempre es necesario decirle al programador lo que está mal; a menudo, él mismo puede resolverlo a partir del contexto. [31] .

static_assert ( tamaño de ( wchar_t ) == 2 );

en línea para variables y constantes globales

Ahora puede escribir en el archivo de encabezado y, al incluir este archivo en archivos cpp, todos se referirán al mismo objeto (el constructor de clase no se llamará repetidamente para cada archivo cpp, a diferencia de o ), inline const ClassName INSTANCE_NAMEconst ClassName INSTANCE_NAMEstatic const ClassName INSTANCE_NAME

Nuevas anotaciones estándar

  • [[fallthrough]]: en una de las secciones del operador, switchintencionalmente "caemos" en la siguiente. Posible implementación del dispositivo Duff
int n = ( cuenta + 7 ) / 8 ; si ( ! cuenta ) regresa ; cambiar ( contar % 8 ) { caso 0 : hacer { * a = * de ++ ; [[ Fallthrough ]]; caso 7 : * a = * de ++ ; [[ Fallthrough ]]; caso 6 : * a = * de ++ ; [[ Fallthrough ]]; caso 5 : * a = * de ++ ; [[ Fallthrough ]]; caso 4 : * a = * de ++ ; [[ Fallthrough ]]; caso 3 : * a = * de ++ ; [[ Fallthrough ]]; caso 2 : * a = * de ++ ; [[ Fallthrough ]]; caso 1 : * a = * de ++ ; } mientras ( -- n > 0 ); }
  • [[nodiscard]]: llamar a una función como un procedimiento se considera un error; por ejemplo, es una función "pura" como string::empty()[32] cuyo único trabajo es devolver un valor, o un protocolo de objeto requiere que se haga algo con el valor devuelto, como en unique_ptr::release(). En el estándar C++20 posterior , se hizo posible especificar un motivo por el que fallaba una llamada.
class SmartPtr { // implementación propia de unique_ptr public : /// Transfiere un objeto administrado al control manual /// @return un puntero a un objeto administrado [[ nodiscard ]] Payload * release (); }; SmartPtrp ; _ Carga útil * datos = p . liberar (); // uso correcto de un puntero inteligente borrar datos ; pág . liberar (); // advertencia: ignorando el valor de retorno de 'SmartPtr::release()', declarado con el atributo nodiscard ( void ) p . liberar (); // así silencian el aviso
  • [[maybe_unused]]: en uno de los modos de compilación ( Windows / POSIX , debug/release) este o aquel elemento no se usa, y esto no es un error.
// QString siempre es UTF-16 y wstring es una plantilla dependiente del sistema operativo < int Sz > void append ( QString & s , unsigned long ch ); // Versión de Windows, wstring = plantilla UTF-16 <> [[ may_unused ]] anexo vacío en línea < 2 > ( QString & s , canal largo sin firmar ) { s . agregar ( static_cast < uint16_t > ( ch ); } // Versión POSIX, wstring = Plantilla UTF-32 < > [[ may_unused ]] void append < 4 > ( QString & s , canal largo sin firmar ) {} // codificación de la posición del código en UTF-16, omitir por brevedad std :: wstring s = L " \U0001F60E " ; // carita sonriente con gafas QString r ; // Para abreviar, hacemos una copia exacta y no se necesita un código tan complejo. // Pero a veces es necesario en algún tipo de procesamiento, por ejemplo, caracteres sin escape. para ( auto c : s ) agregar < tamaño de ( c ) > ( r , c ); O el parámetro no se usa intencionalmente, pero el nombre se deja para fines de documentación. clase ISoccerSeason { // interfaz pública : /// @pre ambos equipos participan esta temporada. /// @return true si un partido se juega entre equipos locales y visitantes /// @warning En una temporada típica de fútbol, ​​ambos equipos jugarán contra equipos locales y visitantes. virtual bool doTeamsPlay ([[ may_unused ]] const Team & home , [[ may_unused ]] const Team & away ) const { return true ; } virtual ~ ISoccerSeason () = predeterminado ; };

Uso de typename en plantillas anidadas

Defecto del lenguaje C++: en plantillas typenamey en classalgunos lugares no intercambiables [33] .

plantilla < plantilla < nombre de tipo > clase X > estructura C ; // OK plantilla < plantilla < nombre de tipo > nombre de tipo X > struct D ; // no compila

Ambas palabras clave se declaran explícitamente intercambiables.

Enlace estructural

Ha surgido una nueva forma de declarar variables para desempaquetar objetos complejos, llamada enlace estructural [34] .

auto [ lugar , fueInsertado ] = algúnMapa . emplazar ( clave , valor );

Funciona para pares, tuplas y otros tipos donde . std::get

Espacio de nombres A::B entrada

Definición de espacios de nombres anidados: [9] [35] namespace A::B {} como abreviatura de namespace A { namespace B {} };

Anotaciones para espacios de nombres y elementos enumerados

Por ejemplo:

enumeración clase TriBool { no , tal vez , , NN [[ tal vez_no usado ]], SIN ESPECIFICAR [[ en desuso ( "Renombrado a QUIZÁS" )]] = QUIZÁS }; constexpr int TriBool_N = static_cast < int > ( TriBool :: NN ); const char * triBoolNames [ TriBool_N ] = { "no" , "tal vez" , "sí" };

Todavía no hay un objetivo declarado [17] [36] , pero esto permitirá a los desarrolladores del compilador encontrar uno; por ejemplo, declarar que el elemento NN es especial y no necesita ser asignado a variables procesadas en switch.

Si al compilar

El concepto de SFINAE hizo posible crear una plantilla simple enable_ifque brinda una funcionalidad diferente para diferentes tipos, pero proporciona un código pesado. En C++17, puede simplificar el programa: el operador if constexpr(expression)instancia el código si la expresión entre paréntesis es verdadera [37] .

plantilla < claseT > _ constexpr T absoluto ( T arg ) { devolver argumento < 0 ? -arg : arg ; _ } plantilla < claseT > _ constexpr auto precision_threshold = T ( 0.000001 ); plantilla < claseT > _ constexpr bool close_enough ( T a , T b ) { if constexpr ( is_punto_flotante_v < T > ) // << !! return absoluto ( a - b ) < precision_threshold < T > ; más devuelve a == b ; }

En este caso, nos aseguramos de que la diferencia entre los números fraccionarios sea pequeña, y los enteros simplemente se verifican por igualdad.

Sintaxis simplificada para operación binaria en plantillas variables

Expresiones empaquetadas [17] [38] :

template < typename ... As > bool foo ( As ... args ) { retorno ( argumentos && ...); }

Representación hexadecimal de números fraccionarios

Mantisa hexadecimal y exponente decimal: 0xC.68p+2, 0x1.P-126, similar a la sustitución %a. C admite esta sintaxis desde la versión 99 [39] .

Inicialización de variables locales en if/switch

Similar a la inicialización de variables locales en for, hace que el código sea más compacto [40] .

if ( auto it = m . find ( key ); it != m . end ()) return it -> second ;

Uso de atributos

// Fue nulo f () { [[ rpr :: kernel , rpr :: target ( cpu , gpu )]] // repetir do_task (); } // Se anuló f () { [[ usando rpr : kernel , target ( cpu , gpu )]] hacer_tarea (); }

Parámetros sin tipo en plantillas

Le permite establecer parámetros de plantilla de cualquier tipo a través de [41] . auto

template < auto X > struct B { static constexpr auto value = X ; }; B < 5 > b1 ; // OK: el tipo de parámetro de plantilla es int B < 'a' > b2 ; // OK: el tipo de parámetro de la plantilla es char B < 2.5 > b3 ; // error: el tipo de parámetro de plantilla no puede ser doble

Capturando el objeto lambda *este

era: . Se convirtió en: [42] . [self = *this]{ self.f(); }[*this]{ f(); }

Puede inicializar una clase de enumeración con un número

enum classa veces se usa para hacer que otro tipo de entero no sea compatible con nada. Ahora las variables de este tipo se pueden inicializar con números [43]

clase de enumeración Manejador : intptr_t { INVÁLIDO = 0 } ; Asa h { 42 }; Mango h = 42 ; // prohibido

Biblioteca

Mejoras menores a la biblioteca

  • Sobrecarga no constante string::data. Se usa para llamar a funciones de cadena de bajo nivel que toman una parte de la memoria de cierta longitud y la llenan con caracteres (por ejemplo, WinAPI ). Antes de C++11 se usaba const_cast<char*>(x.data()), antes de C++17 lo era &x.front().
  • emplace_backun elemento devuelve una referencia. Le permite escribir algo como esto:
v . emplace_back ( "alfa" , "bravo" ). hacer algo ();
  • La biblioteca estándar de C se actualizó de C99 a C11 [44] .
  • Funciones std::size(x), std::begin(x), std::end(x), std::empty(x). Le permite escribir código repetitivo común para matrices y contenedores STL [26] [45] . Además, std:: size es una función necesaria, que a menudo se escribía sola con errores.
  • Añadida especialización parcial [46]bool_constant<bool B> = integral_constant<bool, B>;
  • Se agregaron funciones de propiedad para SFINAE : , , , , (tipo compuesto), (objeto copiable trivialmente y dos objetos cualesquiera con el mismo valor tienen la misma representación interna).is_swappableis_nothrow_swappableis_swappable_withis_nothrow_swappable_withis_aggregatehas_unique_object_representations
  • Biblioteca extendida para trabajar con memoria no inicializada. Existen funciones , , , , , así como sus versiones para n elementos.uninitialized_default_constructuninitialized_value_constructuninitialized_movedestroydestroy_at
  • Nueva plantilla . Simplifica la creación de plantillas SFINAE que se pueden ampliar si existe el tipo T [47] .void_t<T> = void
  • Para versión añadida con objeto buscador. Hay tres buscadores por defecto: Protozoan, Boyer-Moore y Boyer-Moore-Horspool .std::search
  • La nueva función inicializa el tipo T con datos de una tupla.make_from_tuple
  • La nueva constante determina si la variable atómica no es bloqueante .atomic::is_always_lock_free
  • Se agregaron funciones para redondear hacia arriba, hacia abajo y al más cercano .chrono
  • Agregamos las funciones de soltar ( ) y extraer ( ) elementos.map/setmergeextract
  • Tipo añadido .shared_ptr<T>::weak_type = weak_ptr<T>
  • En algunos casos, los asignadores pueden tener un tipo incompleto. Ahora estructuras recursivas como . Los principales compiladores han soportado esto durante mucho tiempo, solo queda especificarlo.struct X { std::vector<X> data; };
  • Se agregaron constructores implícitos a y .pairtuple
  • unique_ptr/shared_ptrpuede trabajar con arreglos estilo C ( ). En C++14, era necesario arrastrar la función de eliminación correcta ( ).shared_ptr<string[]>(new string[n])shared_ptr<string[]>(new string[n], default_delete<string[]>() )
  • El trabajo [48] [49] ha sido refinado .common_type

Nuevo tipo std::string_view

A menudo sucede que necesita pasar una cadena sin cambios a otra sección de código, esto se puede hacer usando los siguientes métodos:

void doSmth ( const char * s ); // ¿Qué sucede si hay un carácter nulo en la cadena? Sí, y el interior de la función se vuelve erróneo void doSmth ( const std :: string & s ); // ¿Qué sucede si la cadena no es una cadena y tenemos que asignar memoria?

C ++ 17 introdujo un tipo string_view , una cadena que tiene solo un puntero y una longitud, sin propiedad, sin administración de memoria y ni siquiera terminando en nulo, por lo que no tiene una extensión c_str(). Solo se pueden cambiar los bordes (comienzo/longitud), no los caracteres. El trabajo del programador es asegurarse de que el objeto no sobreviva al búfer de memoria donde se almacena la cadena, y pasar parámetros es un gran uso para ello. El objeto string_viewes muy pequeño (máquina de 2 bits) y debe pasarse por valor en lugar de por referencia.

string_viewen sí mismo es una abstracción: abstrae el método de almacenamiento de cadenas y solo requiere una cosa: que los datos de texto sean bytes consecutivos en la memoria. Solo estructuras inusuales complejas (por ejemplo, honda/cuerda ) almacenan cadenas aleatorias. Y todo el resto, y , y y varios tipos de arreglos, se convierten en . stringconst char*string_view

Tamaño de línea de caché

Hay dos nuevas constantes, hardware_constructive_interference_sizey hardware_destructive_interference_size. Por lo tanto, el usuario puede evitar el intercambio falso (interferencia destructiva) y mejorar la localidad (interferencia constructiva).

estructura mantener_apartado { alignas ( hardware_destructive_interference_size ) atomic < int > cat ; alignas ( hardware_destructive_interference_size ) atomic < int > dog ; // el gato está lejos del perro, se pueden cambiar desde diferentes hilos. }; estructura -juntos { atómico < int > perro ; cachorro int ; }; estructura de la perrera { //... alignas ( tamaño de ( juntos )) paquete juntos ; //... }; static_assert ( tamaño de ( juntos ) <= hardware_constructive_interference_size ); // asegúrese de que juntos sean una línea de caché.

Teóricamente, ambas constantes deberían ser iguales, pero para soportar arquitecturas heterogéneas, se decidió hacer dos constantes. [cincuenta]

El nuevo tipo shared_mutex

Un mutex que le permite leer en paralelo y escribir en uno [51] . Los bloqueadores para ello se llaman shared_locky unique_lock.

Detección automática de tipo de parámetro de contenedor

Aparecieron funciones en la biblioteca, las llamadas guías de deducción , que le permiten hacer esto:

std :: par p ( 2 , 4.5 ); // una estándar :: vector < int > v = { 1 , 2 , 3 , 4 }; std :: vector x ( v.begin ( ), v.end ( ) ) ; // 2

Nuevas funciones para insertar en una matriz asociativa con una tecla no repetida

Para std::mapy std::unordered_mapse han añadido dos nuevas funciones [52] .

#incluir <iostream> #incluir <mapa> par de clase { público : int valor1 , valor2 ; Par () : valor1 ( 0 ), valor2 ( 0 ) {} Par explícito ( int aValue1 ) : value1 ( aValue1 ), value2 ( 0 ) {} Par ( int aValue1 , int aValue2 ) : valor1 ( unValor1 ), valor2 ( unValor2 ) {} }; int principal () { std :: mapa < std :: cadena , Par > m ; // C++11 m [ "a" ] = Par ( 3 , 4 ); m _ emplace ( "a" , 1 ); // Siempre se crea el par // C++ 17m . insert_or_assign ( "a" , Par ( 3 , 4 )); m _ try_emplace ( "a" , 1 ); // El par se crea cuando es necesario devolver 0 ; }

Nuevas funciones matemáticas

Se han introducido funciones matemáticas no estándar en el espacio de nombres estándar: beta, , , , , , , , , , , [53] [54] . No hay ninguno fuera de std (in ). cyl_bessel_i/j/kcyl_neumann[comp_]ellint_1/2/3expinthermite[assoc_]laguerre[assoc_]legendreriemann_zetasph_besselsph_legendresph_neumannmath.h

De la primera oración (2010): "Esperamos que la adopción de esta propuesta envíe un mensaje a las diversas comunidades informáticas de que, a pesar de la creencia popular, C++ también es bastante adecuado para su industria". Luego no fue aceptado. Ahora, los principales proveedores de bibliotecas ( Dinkumware , Boost , GCC ) ya cuentan con estas características.

También se agregó el cálculo de MCD [55] y LCM [56] , la función de reducción al rango ( ) [57] , la hipotenusa tridimensional . clamphypot(x, y, z)

Biblioteca del sistema de archivos

Una biblioteca de sistema de archivos basada en boost::filesystemle permite: [58]

  • internacionalización automática de nombres de archivos según las características del sistema operativo. La biblioteca oculta la codificación en la que funciona, y ella misma convierte los nombres al deseado, al menos al de un byte definido por la configuración regional y varias variantes de Unicode;
  • recorrido de directorios (incluido recursivo);
  • definición de tipos de archivo (regular, directorio , socket ...);
  • dividir la ruta al archivo en componentes: unidad, directorio, nombre y extensión;
  • creación de directorios, copia de archivos, eliminación de directorios y archivos (incluso recursivo);
  • obtener nombres para archivos temporales .

Tipos de variables

Existía una clase capaz de contener datos de cualquier tipo [59] [60] . Se requieren implementaciones para adaptarse a objetos pequeños sin asignar memoria. La función requiere una coincidencia exacta del tipo y no dará nada si está dentro del archivo . std::anyanyany_castany_cast<double>int

std :: cout << std :: boolalpha ; estándar :: cualquiera a = 1 ; std :: cout << a . tipo (). nombre () << ": " << std :: any_cast < int > ( a ) << std :: endl ; a = 3,14 ; std :: cout << a . tipo (). nombre () << ": " << std :: any_cast < double > ( a ) << std :: endl ; a = verdadero ; std :: cout << a . tipo (). nombre () << ": " << std :: any_cast < bool > ( a ) << std :: endl ; // i: 1 // d: 3.14 // b: verdadero

También hay más simples std::variant<int, bool, double>y std::optional<T>.

Funciones de conversión de número a texto de bajo nivel

Un inconveniente conocido de C ++: para la conversión de números a texto de bajo nivel sin asignación de memoria, debe ejecutar uno pesado y poco confiable sprintf, y la conversión integrada de texto a un número que queda con C es bastante poco confiable.

Ahora hay supervelocidades locales independientes incorporadas from_chars[61] y to_chars[62] . Están diseñados de tal manera que no requieren (y no producen) un cero de cierre y pueden funcionar, por ejemplo, en string_view. Debido a sus limitaciones e independencia local, están destinados principalmente a JSON y XML , donde se necesita una gran velocidad.

Nuevo tipo polymorphic_allocator

Las estructuras de datos STL ( cadenas , vectores , etc.) contienen un parámetro de plantilla: un asignador de memoria. Este asignador funciona como un concepto de programación genérico , no como una interfaz orientada a objetos: la asignación de memoria en el montón y el grupo da como resultado diferentes tipos incompatibles. Una clase  es un comienzo estándar para una tarea rara: según algunas condiciones, asigna memoria en el montón o en el grupo. polymorphic_allocator

Por sí mismo , no  es una interfaz, sino que está asociado a una interfaz . polymorphic_allocatormemory_resource

Nueva plantilla std::invoke

Permite la llamada consistente de funciones, objetos con el operador () ( funtores ) y objetos lambda [63] . También se agregaron funciones , , . is_invocableis_invocable_rinvoke_result

Versiones paralelas de algoritmos STL

Para 69 se han inventado algoritmos de , y versiones paralelas [64] [65] [66] . <algorithm><numeric><memory>

Véase también

Enlaces

  • Proyecto de norma, N4659 , con fecha 21/03/2017

Notas

  1. ISO/IEC 14882:2017 . Consultado el 4 de diciembre de 2017. Archivado desde el original el 17 de mayo de 2013.
  2. Hitos recientes: C++17 casi con funciones completas, segunda ronda de TS ahora en desarrollo . Consultado el 28 de marzo de 2016. Archivado desde el original el 8 de septiembre de 2020.
  3. N3981: ¿¡¿¿Quitando los trigrafos??! (Richard Smith) (6 de mayo de 2014). Consultado el 28 de marzo de 2016. Archivado desde el original el 9 de julio de 2018.
  4. Comentario de IBM sobre la preparación para un futuro adverso de Trigraph en C++17 Archivado el 11 de septiembre de 2018 en Wayback Machine , artículo de IBM N4210, 10-10-2014.
  5. Eliminar el uso obsoleto de la palabra clave de registro . Consultado el 20 de agosto de 2018. Archivado desde el original el 14 de septiembre de 2017.
  6. Quitar operador obsoleto++(bool) . Consultado el 20 de agosto de 2018. Archivado desde el original el 11 de septiembre de 2017.
  7. Eliminación de especificaciones de excepción obsoletas de C++17 . Consultado el 20 de agosto de 2018. Archivado desde el original el 13 de septiembre de 2017.
  8. N4190: Eliminación de auto_ptr, random_shuffle() y cosas antiguas <funcionales> (Stephan T. Lavavej) . Consultado el 28 de marzo de 2016. Archivado desde el original el 20 de octubre de 2017.
  9. 1 2 3 Actualizaciones de mi informe de viaje . Fecha de acceso: 28 de marzo de 2016. Archivado desde el original el 19 de marzo de 2015.
  10. Eliminar alias de iostreams en desuso . Consultado el 20 de agosto de 2018. Archivado desde el original el 22 de agosto de 2017.
  11. Eliminación de la compatibilidad con asignadores en std::function (rev 1) . Consultado el 20 de agosto de 2018. Archivado desde el original el 17 de septiembre de 2017.
  12. Obsolescencia de las piezas de la biblioteca vestigial en C++17 . Consultado el 20 de agosto de 2018. Archivado desde el original el 13 de septiembre de 2017.
  13. Obsoleto <codecvt> . Consultado el 20 de agosto de 2018. Archivado desde el original el 16 de septiembre de 2017.
  14. Resolución propuesta para CA 14 (shared_ptr use_count/unique) . Consultado el 20 de agosto de 2018. Archivado desde el original el 7 de julio de 2017.
  15. Resolviendo GB 55, US 84, US 85, US 86 . Consultado el 20 de agosto de 2018. Archivado desde el original el 5 de julio de 2017.
  16. N4259: Texto para std::uncaught_exceptions (Herb Sutter) . Consultado el 28 de marzo de 2016. Archivado desde el original el 29 de noviembre de 2014.
  17. 1 2 3 4 5 Se adoptaron nuevos documentos de lenguaje central para C++17 . Consultado el 28 de marzo de 2016. Archivado desde el original el 27 de abril de 2015.
  18. Fuente . Consultado el 31 de mayo de 2022. Archivado desde el original el 16 de noviembre de 2017.
  19. C++17 debería referirse a C11 en lugar de C99 . Consultado el 20 de agosto de 2018. Archivado desde el original el 13 de septiembre de 2017.
  20. N3922: Nuevas reglas para la deducción automática de braced-init-list (James Dennett) . Consultado el 28 de marzo de 2016. Archivado desde el original el 10 de agosto de 2015.
  21. Hacer que las especificaciones de excepción formen parte del sistema de tipos . Consultado el 20 de agosto de 2018. Archivado desde el original el 12 de septiembre de 2017.
  22. Asignación de memoria dinámica para datos sobrealineados . Consultado el 20 de agosto de 2018. Archivado desde el original el 8 de septiembre de 2017.
  23. [ http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2016/p0145r3.pdf Orden de evaluación de expresiones de refinamiento para C++ idiomático] . Consultado el 23 de agosto de 2018. Archivado desde el original el 26 de agosto de 2018.
  24. N4268: Permitir evaluación constante para todos los argumentos de plantilla que no sean de tipo (Richard Smith) . Consultado el 28 de marzo de 2016. Archivado desde el original el 12 de marzo de 2016.
  25. Generalización del bucle For basado en rango . Consultado el 23 de agosto de 2018. Archivado desde el original el 5 de octubre de 2017.
  26. 1 2 Nuevos documentos de biblioteca estándar adoptados para C++17 . Consultado el 28 de marzo de 2016. Archivado desde el original el 29 de noviembre de 2014.
  27. N4284: Iteradores contiguos (Jens Maurer) . Consultado el 28 de marzo de 2016. Archivado desde el original el 29 de noviembre de 2014.
  28. N4267: Adición de literales de caracteres u8 (Richard Smith) . Consultado el 28 de marzo de 2016. Archivado desde el original el 28 de octubre de 2015.
  29. Desalentar temporalmente memory_order_consume . Consultado el 20 de agosto de 2018. Archivado desde el original el 16 de enero de 2018.
  30. El Propósito de memory_order_consume en C++11 . Consultado el 15 de agosto de 2019. Archivado desde el original el 11 de noviembre de 2019.
  31. N3928: Ampliación de static_assert, v2 (Walter E. Brown) . Consultado el 28 de marzo de 2016. Archivado desde el original el 11 de agosto de 2015.
  32. Por lo tanto, los autores de PVS-Studio a menudo se quejaban de un error: el programador clear()escribía empty().
  33. N4051: Permitir nombre de tipo en un parámetro de plantilla de plantilla (Richard Smith) . Consultado el 28 de marzo de 2016. Archivado desde el original el 11 de agosto de 2015.
  34. Declaración de enlace estructurado (desde C++17) Archivado el 8 de septiembre de 2020 en Wayback Machine en.cppreference.com
  35. N4230: Definición de espacio de nombres anidado (Robert Kawulak, Andrew Tomazos) . Consultado el 28 de marzo de 2016. Archivado desde el original el 3 de agosto de 2015.
  36. N4266: Atributos para espacios de nombres y enumeradores (Richard Smith) . Fecha de acceso: 28 de marzo de 2016. Archivado desde el original el 6 de marzo de 2016.
  37. constexpr if: Una sintaxis ligeramente diferente . Consultado el 20 de agosto de 2018. Archivado desde el original el 7 de octubre de 2017.
  38. N4295: Expresiones plegables (Andrew Sutton, Richard Smith) . Consultado el 28 de marzo de 2016. Archivado desde el original el 4 de abril de 2015.
  39. Literales flotantes hexadecimales para C++ . Consultado el 12 de junio de 2019. Archivado desde el original el 22 de agosto de 2017.
  40. ↑ Instrucciones de selección con inicializador . Consultado el 12 de junio de 2019. Archivado desde el original el 6 de octubre de 2017.
  41. Declaración de parámetros de plantilla que no son de tipo con auto . Consultado el 7 de agosto de 2020. Archivado desde el original el 16 de septiembre de 2017.
  42. Captura Lambda de *this por Value as [=,*this ] . Consultado el 7 de agosto de 2020. Archivado desde el original el 22 de agosto de 2017.
  43. Reglas de construcción para valores de clase enum . Consultado el 7 de agosto de 2020. Archivado desde el original el 9 de diciembre de 2017.
  44. C++17 debería referirse a C11 en lugar de C99 . Consultado el 18 de diciembre de 2016. Archivado desde el original el 13 de noviembre de 2016.
  45. N4280: Tamaño de no miembros() y más (Riccardo Marcangelo) . Fecha de acceso: 28 de marzo de 2016. Archivado desde el original el 9 de marzo de 2015.
  46. Redacción para bool_constant, revisión 1 . Consultado el 1 de enero de 2020. Archivado desde el original el 14 de octubre de 2017.
  47. Copia archivada . Consultado el 1 de enero de 2020. Archivado desde el original el 28 de agosto de 2017.
  48. Copia archivada . Consultado el 1 de enero de 2020. Archivado desde el original el 10 de octubre de 2017.
  49. Copia archivada . Consultado el 1 de enero de 2020. Archivado desde el original el 5 de julio de 2017.
  50. P0154R1 constexpr std::hardware_{constructive,destructive}_interference_size .
  51. std::shared_mutex-cppreference.com . Consultado el 30 de agosto de 2019. Archivado desde el original el 30 de agosto de 2019.
  52. Interfaz de inserción mejorada para std::{unordered_,}map (revisado) . Consultado el 28 de marzo de 2016. Archivado desde el original el 27 de abril de 2015.
  53. Copia archivada . Consultado el 20 de agosto de 2019. Archivado desde el original el 17 de septiembre de 2019.
  54. Funciones especiales matemáticas para C++17, v5 . Consultado el 28 de marzo de 2016. Archivado desde el original el 5 de abril de 2016.
  55. std::gcd-cppreference.com . Consultado el 30 de agosto de 2019. Archivado desde el original el 28 de marzo de 2019.
  56. std::lcm-cppreference.com . Consultado el 30 de agosto de 2019. Archivado desde el original el 28 de marzo de 2019.
  57. std::clamp - cppreference.com . Consultado el 30 de agosto de 2019. Archivado desde el original el 30 de agosto de 2019.
  58. Propuesta de biblioteca de sistema de archivos (Beman Dawes) . Consultado el 28 de marzo de 2016. Archivado desde el original el 20 de julio de 2016.
  59. Extensiones de C++ para Library Fundamentals, Versión 2, Borrador de trabajo . Consultado el 30 de agosto de 2019. Archivado desde el original el 25 de agosto de 2019.
  60. std::any - cppreference.com . Consultado el 30 de agosto de 2019. Archivado desde el original el 30 de agosto de 2019.
  61. std::from_chars-cppreference.com . Consultado el 30 de agosto de 2019. Archivado desde el original el 30 de agosto de 2019.
  62. std::to_chars-cppreference.com . Consultado el 30 de agosto de 2019. Archivado desde el original el 30 de agosto de 2019.
  63. Una propuesta para agregar una plantilla de función de invocación (Revisión 1) . Consultado el 1 de enero de 2020. Archivado desde el original el 6 de octubre de 2017.
  64. Extensiones para paralelismo - cppreference.com . Consultado el 5 de febrero de 2021. Archivado desde el original el 12 de noviembre de 2020.
  65. El TS de paralelismo debe ser estandarizado . Consultado el 28 de marzo de 2016. Archivado desde el original el 5 de abril de 2016.
  66. Uso de algoritmos paralelos de C++17 para un mejor rendimiento | Blog del equipo de C++ . Consultado el 5 de febrero de 2021. Archivado desde el original el 24 de enero de 2021.