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, la sustitución de instancias antiguas de operator void*()
. De acuerdo, el código que esto romperá es probablemente un código que no debería haber sido válido en primer lugar, pero aún así es un cambio importante: los programas que solían ser válidos ya no lo son.
¿Hay otros cambios importantes?
export
palabra clave? Me traeré el abrigo.mystream.good()
¿no es lo mismo quebool(mystream)
?good()
es verdadero si no se establece ninguna bandera.bool(mystream)
sigue siendo falso si soloeofbit
está configurado.!mystream.fail()
Sería el equivalente correcto.Respuestas:
El FDIS tiene una sección para 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 en las que no sé exactamente las implicaciones de, por lo que las dejo para que otros las expliquen.
Lenguaje central
(Es cierto que no es realmente un problema de compatibilidad para la mayoría de las personas).
Ejemplo por mi parte:
Tal tamaño de trucos han sido utilizados por algunos SFINAE, y deben cambiarse ahora :)
Ejemplo por mi parte:
Este código llama
terminate
en C ++ 0x, pero no en C ++ 03. Porque la especificación de excepción implícita deA::~A
en C ++ 0x esnoexcept(true)
.En C ++ 03,
>>
siempre sería el token shift-operator.Ejemplo por mi parte:
En C ++ 03, esto llama
f(long)
, pero en C ++ 0x, esto llamaf(int)
. Cabe señalar que tanto en C ++ 03 como en C ++ 0x, las siguientes llamadasf(B)
(el contexto de instanciación solo considera las declaraciones de enlaces externos).La mejor coincidencia
f(A)
No se toma la , ya que no tiene enlace externo.Cambios de biblioteca
fuente
export
, creo que las otras TU no tendrían que depender de la instanciación explícita, sino que podrían crear una instancia de la plantilla. Entonces marcaría una diferencia si las funciones de vinculación interna son visibles en el contexto de instanciación.El significado de la palabra clave automática cambió.
fuente
auto
palabra clave, algo está muy mal con su código. ¿Por qué demonios lo usarías?auto
sigue siendo válido en C ++ 11.int main() { auto int i = 0; return i; }
es C ++ 03 perfectamente válido, pero es un error de sintaxis en C ++ 11. La única advertencia que puedo hacer que los compiladores den en modo C ++ 03 es una advertencia sobre compatibilidad.Rompiendo el cambio?
Bueno, por un lado, si se ha utilizado
decltype
,constexpr
,nullptr
, etc, como identificadores entonces usted puede estar en problemas ...fuente
Algunas incompatibilidades principales que no están cubiertas por la sección de incompatibilidades:
C ++ 0x trata el nombre de la clase inyectada como una plantilla, si el nombre se pasa como un argumento a un parámetro de plantilla de plantilla, y como un tipo si se pasa a un parámetro de tipo de plantilla.
El código válido de C ++ 03 puede comportarse de manera diferente si se basa en que el nombre de la clase inyectada sea siempre un tipo en estos escenarios. Código de ejemplo tomado de mi PR clang
En C ++ 03, el código llama al segundo las
g
dos veces.C ++ 0x hace que algunos nombres que eran dependientes en C ++ 03 ahora no sean dependientes. Y requiere la búsqueda de nombres para nombres calificados no dependientes que se refieren a miembros de la plantilla de clase actual para que se repitan en la instanciación, y requiere la verificación de que estos nombres buscan de la misma manera que en el contexto de definición de plantilla.
Es posible que el código C ++ 03 válido que depende de la regla de dominio ya no se compile debido a este cambio.
Ejemplo:
Este código válido de C ++ 03 que llama
A<int>::f
no es válido en C ++ 0x, porque la búsqueda de nombres al crear instancias se encuentraA<int>::f
en lugar deB::f
, lo que causa un conflicto con la búsqueda en definición.En este punto, no está claro si eso es un defecto en el FDIS. El comité es consciente de esto y evaluará la situación.
Una declaración de uso donde la última parte es la misma que el identificador en la última parte del calificador en el nombre calificado que denota una clase base, que la declaración de uso ahora nombra al constructor, en lugar de miembros con ese nombre.
Ejemplo:
El código de ejemplo anterior está bien formado en C ++ 03, pero está mal formado en C ++ 0x, ya
A::B
que todavía no se puede acceder a élmain
.fuente
La falla de extracción de corriente se trata de manera diferente.
Ejemplo
Propuesta de cambio
http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2011/n3246.html#23
Referencia estándar
Implementaciones
GCC 4.8 da salida correctamente a C ++ 11 :
GCC 4.5-4.8 todos los resultados para C ++ 03 lo siguiente, lo que parece ser un error:
Visual C ++ 2008 Express produce correctamente los resultados para C ++ 03:
Visual C ++ 2012 Express genera incorrectamente resultados para C ++ 11, lo que parece ser un problema de estado de implementación:
fuente
¿Cómo es la introducción de operadores de conversión explícitos un cambio radical? La versión anterior seguirá siendo tan "válida" como antes.Sí, el cambio de
operator void*() const
aexplicit operator bool() const
será un cambio radical, pero solo si se usa de una manera incorrecta dentro y fuera de sí mismo. El código conforme no se romperá.Ahora, otro cambio importante es la prohibición de reducir las conversiones durante la inicialización agregada :
Editar : Solo recuerdo,
std::identity<T>
se eliminará en C ++ 0x (ver la nota). Es una estructura conveniente para hacer que los tipos sean dependientes. Dado que la estructura realmente no hace mucho, esto debería solucionarlo:fuente
operator void*
.bool ok = cin >> a; cout << "done reading" << endl; if (ok) { ... }
no hay nada realmente malo en eso en C ++ 03, pero se ha convertido en un error en C ++ 11. (Nota: GCC 4.9 todavía tieneoperator void*() const
aquí, por lo que acepta el código en C ++ 11 Modo.)std::identity<T>
no se eliminó en C ++ 11, porque no era parte de C ++ 03. Existió brevemente en el borrador para C ++ 11, y se eliminó del borrador antes de la estandarización.Hay numerosos cambios en la biblioteca de contenedores que permiten un código más eficiente pero silenciosamente rompen la compatibilidad con versiones anteriores en algunos casos.
Considere, por ejemplo, la
std::vector
construcción predeterminada, C ++ 0x y los cambios de última hora .fuente
Se ha discutido mucho sobre el movimiento implícito que rompe la compatibilidad con versiones anteriores
( una página anterior con discusión relevante )
Si lee los comentarios, el retorno de movimiento implícito también es un cambio radical.
fuente
C ++ 03: válido.
C ++ 0x:
error: parameter declared 'auto'
fuente
struct x
y sin nombre.Características del lenguaje
>>
Componentes de biblioteca estándar
Características en desuso
fuente