¿Qué cambios importantes se introducen en C++ 11?

Resuelto R. Martinho Fernandes asked hace 13 años • 0 respuestas

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?

R. Martinho Fernandes avatar Jun 19 '11 06:06 R. Martinho Fernandes
Aceptado

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 autocomo 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 terminateen C++ 0x, pero no en C++03. Debido a que la especificación de excepción implícita A::~Aen C++ 0x es noexcept(true).


Una declaración válida de C++ 2003 que contiene exportestá 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 #includeslos 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 posixahora está reservado para la estandarización.


El código C++ 2003 válido que define override, final, carries_dependencyo noreturncomo macros no es válido en C++ 0x.

Johannes Schaub - litb avatar Jun 19 '2011 11:06 Johannes Schaub - litb

El significado de la palabra clave auto cambió.

 avatar Jun 19 '2011 00:06