[c++] ¿Qué cambios de ruptura se introducen en C ++ 11?



Answers

El significado de la palabra clave auto ha cambiado.

Question

Sé que al menos uno de los cambios en C ++ 11 provocará que algunos códigos antiguos dejen de compilar: la introducción del explicit operator bool() en la biblioteca estándar, que reemplaza las instancias antiguas de operator void*() . De acuerdo, el código que esto romperá probablemente sea un código que no debería haber sido válido desde el principio, pero aún así es un cambio radical: los programas que solían ser válidos ya no lo son.

¿Hay algún otro cambio de ruptura?




Características del lenguaje

  1. Inicialización uniforme y general usando {}
  2. auto
  3. Prevención del estrechamiento
  4. constexpr
  5. Rango basado en bucle
  6. nullptr
  7. clase enum
  8. static_assert
  9. std :: initializer_list
  10. Referencias de Rvalue (semántica de movimiento)
  11. >>
  12. Lambdas
  13. Plantillas variables
  14. Tipo y alias de plantilla
  15. Caracteres Unicode
  16. tipo entero largo y largo
  17. Alignas y Alignof
  18. decltype
  19. Literales de cadena sin procesar
  20. POD generalizado
  21. Uniones generalizadas
  22. Clases locales como argumentos de plantilla
  23. Sufijo tipo de retorno sintaxis
  24. [[carries_dependency]] y [[noreturn]]
  25. noexcept especificador
  26. operador no exceptuado
  27. C99 características:
    • tipos integrales extendidos
    • concatenación de cuerda estrecha / ancha
    • _ _ STDC_HOSTED _ _
    • _Pragma (X)
    • macros vararg y argumentos de macro vacíos
  28. _ _ func _ _
  29. Espacios de nombres en línea
  30. Delegar constructores
  31. Inicializadores de miembros en la clase
  32. predeterminado y eliminar
  33. Operadores de conversión explícitos
  34. Literales definidos por el usuario
  35. Plantillas externas
  36. Argumentos de plantilla predeterminados para plantillas de funciones
  37. Heredar constructores
  38. anular y final
  39. Regla SFINAE más simple y más general
  40. Modelo de memoria
  41. thread_local

Componentes de biblioteca estándar

  1. initializer_list para contenedores
  2. Mover semántica para contenedores
  3. forward_list
  4. Contenedores hash
    • unordered_map
    • unordered_multimap
    • unordered_set
    • unordered_multiset
  5. Punteros de gestión de recursos
    • unique_ptr
    • shared_ptr
    • weak_ptr
  6. Soporte de simultaneidad
    • hilo
    • mutexes
    • cabellos
    • variables de condición
  7. Soporte de simultaneidad de alto nivel
    • packaged_thread
    • futuro
    • promesa
    • asincrónico
  8. tuplas
  9. regex
  10. Números al azar
    • uniform_int_distribution
    • distribución normal
    • random_engine
    • etc.
  11. Nombres de tipos enteros, como int16_t, uint32_t e int_fast64_t
  12. formación
  13. Copiar y volver a lanzar excepciones
  14. error del sistema
  15. operaciones emplace () para contenedores
  16. funciones constexpr
  17. Uso sistemático de funciones sin excepción
  18. función y enlace
  19. Cadena a conversiones de valor numérico
  20. Asignadores con alcance
  21. Escriba rasgos
  22. Utilidades de tiempo: duración y punto de tiempo
  23. proporción
  24. quick_exit
  25. Más algoritmos, como move (), copy_if () y is_sorted ()
  26. Recolección de basura ABI
  27. atomística

Características desaprobadas

  1. Generación del constructor de copia y la asignación de copia para una clase con un destructor.
  2. Asigna un literal de cadena a un char *.
  3. Especificación de la excepción C ++ 98
    • unexcepted_handler
    • set_unexpected
    • get_unexpected
    • inesperado
  4. Objetos de función y funciones asociadas
  5. auto_ptr
  6. registro
  7. ++ en un bool
  8. exportar
  9. Moldes de estilo C






Algunas incompatibilidades principales que no están cubiertas por la sección de incompatibilidades:

C ++ 0x trata el nombre de clase inyectado 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 clase inyectado sea siempre un tipo en estos escenarios. Código de ejemplo tomado de mi clang PR

template<template<typename> class X>
struct M { };

template<template<typename> class X>
void g(int = 0); // #1

template<typename T>
void g(long = 0); // #2

template<typename T>
struct A {
  void f() {
    g<A>(); /* is ambiguous in C++0x */
    g<A>(1); /* should choose #1 in C++0x */
  }
};

void h() {
  A<int> a;
  a.f();
}

En C ++ 03, el código llama al segundo g ambas ocasiones.

C ++ 0x hace que algunos nombres que dependían en C ++ 03 sean ahora no dependientes. Y requiere la búsqueda de nombre para nombres calificados no dependientes que se refieren a miembros de la plantilla de clase actual que se repetirá en instanciación, y requiere verificación de que estos nombres se buscan de la misma manera que en el contexto de definición de plantilla.

El código válido de C ++ 03 que depende de la regla de dominación ya no se puede compilar debido a este cambio.

Ejemplo:

struct B { void f(); };

template<typename T>
struct A : virtual B { void f(); };

template<typename T>
struct C : virtual B, A<T> {
  void g() { this->f(); }
};

int main() { C<int> c; c.g(); }

Este código válido de C ++ 03 que llama a A<int>::f no es válido en C ++ 0x, porque la búsqueda de nombres al momento de buscar encontrará A<int>::f en vez de B::f , lo que ocasiona 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 using 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 using declaration ahora nombra al constructor, en lugar de los miembros con ese nombre.

Ejemplo:

struct A { protected: int B; };
typedef A B;

struct C : B {
  // inheriting constructor, instead of bringing A::B into scope
  using B::B;
};

int main() { C c; c.B = 0; }

El código de ejemplo anterior está bien formado en C ++ 03, pero mal formado en C ++ 0x, ya que A::B sigue siendo inaccesible en main .




La falla de extracción de flujo se trata de manera diferente.

Ejemplo

#include <sstream>
#include <cassert>

int main()
{
   std::stringstream ss;
   ss << '!';

   int x = -1;

   assert(!(ss >> x)); // C++03 and C++11
   assert(x == -1);    // C++03
   assert(x == 0);     // C++11
}

Cambiar propuesta

http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2011/n3246.html#23

Referencia estándar

[C++03: 22.2.2.1.2/11]: el resultado del procesamiento de la etapa 2 puede ser uno de

  • Se ha acumulado una secuencia de caracteres en la etapa 2 que se convierte (de acuerdo con las reglas de scanf ) a un valor del tipo de val . Este valor se almacena en val y ios_base::goodbit se almacena en err .
  • La secuencia de caracteres acumulados en la etapa 2 hubiera causado que scanf informara una falla de entrada. ios_base::failbit está asignado a err . [ed: nada está almacenado en val .]

[C++11: 22.4.2.1.2/3]: [..] El valor numérico a almacenar puede ser uno de:

  • cero, si la función de conversión no puede convertir todo el campo . ios_base::failbit está asignado a err .
  • el valor representable más positivo, si el campo representa un valor demasiado grande positivo para ser representado en val . ios_base::failbit está asignado a err .
  • el valor representable más negativo o cero para un tipo entero sin signo, si el campo representa un valor demasiado grande negativo para ser representado en val . ios_base::failbit está asignado a err .
  • el valor convertido, de lo contrario.

El valor numérico resultante se almacena en val .

Implementaciones

  • GCC 4.8 muestra correctamente para C ++ 11 :

    Aserción `x == -1 'falló

  • GCC 4.5-4.8 toda la salida para C ++ 03 la siguiente, que parece ser un error:

    Aserción `x == -1 'falló

  • Visual C ++ 2008 Express genera correctamente para C ++ 03:

    La aserción falló: x == 0

  • Visual C ++ 2012 Express genera incorrectamente para C ++ 11, lo que parece ser un problema de estado de implementación:

    La aserción falló: x == 0




Related



Tags

c++ c++   c++11