¿Qué cambios importantes se introducen en C++ 11?
Sé que al menos uno de los cambios en C++ 11 que hará que algún código antiguo deje de compilarse: la introducción de explicit operator bool()
en la biblioteca estándar, reemplazando instancias antiguas deoperator void*()
. Por supuesto, el código que esto romperá probablemente sea un código que no debería haber sido válido en primer lugar, pero sigue siendo un cambio importante: los programas que solían ser válidos ya no lo son.
¿Hay otros cambios importantes?
El FDIS tiene un apartado de incompatibilidades, en el apéndice C.2
"C++ e ISO C++ 2003".
Resumen, parafraseando el FDIS aquí, para que sea (mejor) adecuado como respuesta SO. Agregué algunos ejemplos propios para ilustrar las diferencias.
Hay algunas incompatibilidades relacionadas con la biblioteca de las que no sé exactamente las implicaciones, así que las dejo para que otros las analicen.
lenguaje central
#define u8 "abc"
const char *s = u8"def"; // Previously "abcdef", now "def"
#define _x "there"
"hello"_x // now a user-defined-string-literal. Previously, expanded _x .
Nuevas palabras clave: aligns, alignof, char16_t, char32_t, constexpr, decltype, noexcept, nullptr, static_assert y thread_local
Ciertos literales enteros más grandes de lo que puede representarse con long podrían cambiar de un tipo entero sin signo a long con signo.
El código C++ 2003 válido que utiliza división de enteros redondea el resultado hacia 0 o hacia el infinito negativo, mientras que C++0x siempre redondea el resultado hacia 0.
(Es cierto que no es realmente un problema de compatibilidad para la mayoría de las personas).
El código válido de C++ 2003 que utiliza la palabra clave
auto
como especificador de clase de almacenamiento puede no ser válido en C++ 0x.
Las conversiones limitadas provocan incompatibilidades con C++03. Por ejemplo, el siguiente código es válido en C++ 2003 pero no válido en esta Norma Internacional porque double a int es una conversión restringida:
int x[] = { 2.0 };
Las funciones miembro especiales declaradas implícitamente se definen como eliminadas cuando la definición implícita habría estado mal formada.
Un programa C++ 2003 válido que utiliza una de estas funciones miembro especiales en un contexto donde no se requiere la definición (por ejemplo, en una expresión que potencialmente no se evalúa) queda mal formado.
Ejemplo mío:
struct A { private: A(); };
struct B : A { };
int main() { sizeof B(); /* valid in C++03, invalid in C++0x */ }
Algunos SFINAE han utilizado trucos de este tamaño y es necesario cambiarlos ahora :)
Los destructores declarados por el usuario tienen una especificación de excepción implícita.
Ejemplo mío:
struct A {
~A() { throw "foo"; }
};
int main() { try { A a; } catch(...) { } }
Este código llama terminate
en C++ 0x, pero no en C++03. Debido a que la especificación de excepción implícita A::~A
en C++ 0x es noexcept(true)
.
Una declaración válida de C++ 2003 que contiene
export
está mal formada en C++ 0x.
Una expresión válida de C++ 2003 que contenga
>
seguida inmediatamente de otra>
ahora puede considerarse como el cierre de dos plantillas.
En C++03, >>
siempre sería el token del operador de turno.
Permitir llamadas dependientes de funciones con enlace interno.
Ejemplo mío:
static void f(int) { }
void f(long) { }
template<typename T>
void g(T t) { f(t); }
int main() { g(0); }
En C++03, esto llama f(long)
, pero en C++0x, esto llama f(int)
. Cabe señalar que tanto en C++ 03 como en C++ 0x, las siguientes llamadas f(B)
(el contexto de creación de instancias todavía solo considera declaraciones de enlace externo).
struct B { };
struct A : B { };
template<typename T>
void g(T t) { f(t); }
static void f(A) { }
void f(B) { }
int main() { A a; g(a); }
No se toma la mejor correspondencia f(A)
, porque no tiene vinculación externa.
Cambios de biblioteca
El código válido de C++ 2003 que utiliza cualquier identificador agregado a la biblioteca estándar de C++ de C++ 0x puede no compilarse o producir resultados diferentes en este estándar internacional.
El código válido de C++ 2003 indica que
#includes
los encabezados con nombres de nuevos encabezados de biblioteca estándar C++ 0x pueden no ser válidos en esta norma internacional.
Es posible que el código válido de C++ 2003 que se ha compilado esperando que se realice el intercambio
<algorithm>
deba incluir<utility>
El espacio de nombres global
posix
ahora está reservado para la estandarización.
El código C++ 2003 válido que define
override
,final
,carries_dependency
onoreturn
como macros no es válido en C++ 0x.
El significado de la palabra clave auto cambió.