El comité ISO de estandarización del lenguaje C++ ha completado y aprobado la versión final de la especificación que constituye el estándar internacional "C++26". Las capacidades presentadas en la especificación ya son parcialmente compatibles con los compiladores GCC, Clang y Microsoft Visual C++. Las bibliotecas estándar que soportan C++26 se implementan en el marco del proyecto Boost.
En los próximos dos meses, la especificación aprobada se encontrará en la etapa de preparación del documento para su publicación, donde se realizarán revisiones editoriales para corregir errores ortográficos y tipográficos. A principios de noviembre, el documento resultante se enviará a la ISO para su publicación bajo el nombre formal ISO/IEC 14882:2026.
Características principales de C++26:
- Se han implementado elementos de programación por contrato (Contracts), que permiten definir especificaciones formales de interfaces mediante tres nuevos operadores: pre (precondición), post (postcondición) y contract_assert (verificación de afirmaciones). El operador "pre" define las condiciones previas que deben cumplirse antes de la llamada (verificación de datos de entrada); "post" define las condiciones que deben cumplirse después de la ejecución (requisitos sobre los datos de salida); contract_assert son las condiciones bajo las cuales se producen excepciones. Esta funcionalidad estará disponible en GCC 16. int f(const int x) pre (x != 1) // requisitos de entrada post (r : r == x && r != 2) // requisitos del resultado; r — valor del resultado { contract_assert (x != 3); return x; }
- Se ha añadido soporte para la reflexión (Reflection), que permite rastrear y modificar elementos del programa en la etapa de compilación. Se han introducido nuevos operadores "^^" para obtener metainformación sobre la construcción gramatical y "[:…:]" para realizar la transformación inversa. Se propone la biblioteca std::meta para la conversión y el procesamiento de la información obtenida durante la inspección, así como capacidades como cálculos con constantes. El soporte para la reflexión se añadirá en GCC 16. constexpr int i = 42, j = 42; constexpr std::meta::info r = ^^i, s = ^^i; static_assert(r == r && r == s); static_assert(^^i != ^^j); // 'i' y 'j' tienen diferentes valores. static_assert(constant_of(^^i) == constant_of(^^j)); // 'i' y 'j' son iguales static_assert(^^i != std::meta::reflect_constant(42)); // es diferente de 42
- Se añadió el operador «template for» para iterar sobre elementos, como paquetes de parámetros, objetos similares a tuplas y resultados de reflexión (metaobjetos), en la etapa de compilación al estilo de un bucle normal. Al ejecutar «template for», el cuerpo del bucle se expande para cada elemento y cada iteración se procesa en un ámbito separado, en el que la variable cambiante en el bucle es una constante. En el contexto de la reflexión, «template for» puede aplicarse para recorrer las propiedades de clases o enumeraciones. La funcionalidad estará disponible en GCC 16. void f() { template for (constexpr int I : std::array{1, 2, 3}) { static_assert(I < 4); } } se expandirá en: void f() { { constexpr auto&& __range = std::array{1, 2, 3}; constexpr auto __begin = __range.begin(); constexpr auto __expansion_size = __range.end() - __begin; // 3 { constexpr int I = *(__begin + 0); static_assert(I < 4); } { constexpr int I = *(__begin + 1); static_assert(I < 4); } { constexpr int I = *(__begin + 2); static_assert(I < 4); } } }
- Se añadió el marco std::execution para la ejecución asíncrona y paralela de código. Se proporcionan los objetos scheduler, que define el planificador de trabajos (hilo, grupo de hilos, GPU, bucle de eventos), sender, que define el trabajo a realizar, y receiver, que es el controlador del resultado. using namespace std::execution; scheduler auto sch = thread_pool.scheduler(); sender auto begin = schedule(sch); sender auto hi = then(begin, []{ std::cout << "¡Hola mundo! Tengo un int."; return 13; }); sender auto add_42 = then(hi, [](int arg) { return arg + 42; }); auto [i] = this_thread::sync_wait(add_42).value();
- Se añadió la biblioteca std::simd para paralelizar la ejecución de operaciones sobre datos utilizando conjuntos de instrucciones SIMD, como AVX-512 y NEON, con el uso del sistema de tipos estándar de C++. std::simd a = {1.0f, 2.0f, 3.0f, 4.0f}; std::simd b = {5.0f, 6.0f, 7.0f, 8.0f}; std::simd result = a + b;
- Se propuso la implementación del vector (array) de tamaño variable std::inplace_vector, que se aloja en la pila, cuyo tamaño se define en la etapa de compilación. La API es similar a std::vector, pero los elementos del array se almacenan no en el ‘heap’, sino dentro del objeto. inplace_vector a(10); inplace_vector b(std::move(a)); assert(a.size() == 10);
- Se añadió la directiva «#embed», destinada a incrustar recursos binarios en el código. const unsigned char icon_display_data[] = { #embed "art.png" };
- Se ha añadido soporte para la generación y manejo de excepciones en la etapa de compilación ante errores en el contexto de constexpr. constexpr std::optional checked_divide(unsigned n, unsigned d) { try { return divide(n, d); } catch (…) { return std::nullopt; } } constexpr date parse_date(std::string_view input) { auto [correct, year, month, day] = ctre::match(input); if (!correct) { throw incorrect_date{input}; } return build_date(year, month, day); }
- Se ha implementado la estructura de datos std::hive para el almacenamiento no ordenado de datos y la reutilización de memoria liberada tras la eliminación de elementos. Esta estructura está optimizada para cargas con alta intensidad de adiciones y eliminaciones de elementos en un orden arbitrario. A diferencia de los arreglos, la eliminación de un elemento en std::hive no provoca el desplazamiento de otros elementos, sino que marca el elemento eliminado como vacío, con la posterior ocupación de la posición liberada al añadir un nuevo elemento.
- Se ha añadido la biblioteca std::linalg con API para álgebra lineal, basada en BLAS.
- Se ha incluido soporte para el mecanismo de sincronización Hazard pointer, que permite prevenir la liberación de memoria de objetos que todavía están siendo utilizados en otros hilos, sin necesidad de establecer bloqueos. Al eliminar un objeto, este solo se marca como eliminado, pero la memoria ocupada por el objeto se libera solo después de que todos los hilos hayan retirado el puntero de riesgo establecido durante el uso del objeto.
- Se ha añadido soporte para el mecanismo de sincronización RCU (Read-Copy Update) — en operaciones de escritura, se crea una nueva instancia del objeto, mientras que las operaciones de lectura no se bloquean, continuando con la antigua instancia. Una vez que se finaliza el cambio, la nueva instancia se activa y las nuevas operaciones de lectura se realizan con ella, mientras que la instancia antigua se elimina después de que los hilos que la leen hayan finalizado.
- Se han realizado cambios para reforzar la seguridad de la biblioteca estándar, tales como cheques de valores permitidos y desbordamientos de búfer. Por ejemplo, al acceder al elemento «constexpr reference operator[](size_type idx) const;», se añade una verificación de la condición «idx < size()».
- Se ha proporcionado la posibilidad de utilizar la palabra clave «constexpr» con una variante del operador «new» (placement new) para colocar un objeto en memoria previamente asignada durante la compilación.
- Se ha añadido soporte para los enlaces estructurados (structured binding) en el contexto de «constexpr», es decir, las referencias a expresiones constantes ahora pueden ser expresiones constantes en sí mismas. El soporte se ha implementado para arreglos y estructuras simples. constexpr int arr[] = {1, 2}; constexpr auto [x, y] = arr;
- Se ha añadido la posibilidad de usar la sintaxis «…» en los enlaces estructurados para indicar paquetes (pack) que capturan el número restante de elementos de la secuencia asignada. auto [x,y,z] = f(); // se asignarán tres elementos devueltos por f() a las variables x, y, z. auto […xs] = f(); // se asignarán todos los elementos devueltos por f() al paquete xs. auto [x, …rest] = f(); // x tendrá el primer elemento, y rest tendrá los restantes. auto [x, y, …rest] = f(); // x tendrá el primer elemento, y tendrá el segundo, y rest tendrá el tercero. auto [x, …rest, z] = f(); // x tendrá el primero, rest tendrá el segundo, y z tendrá el tercero.
- Se ha añadido soporte para la «movilidad trivial» de tipos (Trivial Relocatability), permitiendo optimizar los movimientos de objetos de un tipo dado mediante su clonación en memoria sin invocar constructores o destructores. Para las clases, se han implementado las propiedades memberwise_trivially_relocatable y memberwise_replaceable, y se han añadido funciones trivially_relocate_at y trivially_relocate para el movimiento de uno o varios objetos a bajo nivel.
- Se ha implementado el soporte para vincular la función main() al módulo global y definir la función main() en módulos nombrados.
- Se ha añadido el operador variadico «friend» («friend Ts…»).
- Se han implementado atributos para los enlaces estructurados;
- Se ha añadido la sintaxis ‘= delete(«razón»)’.
- Se han incluido los caracteres «@», «$» y «`» en el conjunto básico de caracteres.
- Se ha proporcionado la posibilidad de aplicar el enlace estructurado (structured binding) como condición en los operadores if y switch.
- Se ha añadido la posibilidad de utilizar múltiples variables de relleno con el nombre «_» en un mismo ámbito, por ejemplo, ahora son correctas las siguientes construcciones: struct S { int _, _; }; void func() { int _, _; } void other() { int _; // anteriormente se mostraba una advertencia en modo -Wunused }
- Se ha proporcionado la posibilidad de utilizar literales de cadena en un contexto en el que no se utilizan para inicializar un arreglo de caracteres y no se incluyen en el código resultante, sino que se aplican solo durante la compilación para mensajes de diagnóstico y preprocesamiento, por ejemplo, como parámetros de directivas y atributos _Pragma, asm, extern, static_assert, [[deprecated]] y [[nodiscard]].
- Se han añadido funciones integradas: «__builtin_is_within_lifetime» para comprobar la actividad de alternativas en uniones y «__builtin_is_virtual_base_of» para verificar si una clase base es virtual.
- Se han implementado bucles infinitos triviales sin comportamiento indefnido.
- Se ha asegurado la salida de un error al eliminar un puntero a un tipo incompleto.
- Se ha declarado obsoleta la sintaxis de definición de parámetros variáticos con puntos suspensivos sin una coma previa (por ejemplo, al indicar «void e(int…)» en lugar de «void e(int, …)»).
- Se prohíbe el uso de macros para declarar módulos.
- Se ha trasladado a la categoría de obsoleto la ejecución de conversiones implícitas de valores enumerados en cálculos aritméticos. int main() { enum E1 { e }; enum E2 { f }; bool b = e <= 3.7; // obsoleto int k = f - e; // obsoleto int x = +f - e; // OK }
- Se ha descontinuado el soporte para la comparación directa de arreglos. int arr1[5]; int arr2[5]; bool same = arr1 == arr2;
- Se ha declarado obsoleta la clase de plantilla is_trivial.
Fuente: opennet.ru
