fbpx
Wikipedia

C++11

C++11 es una versión del lenguaje de programación C++ estándar aprobado por la Organización Internacional de Normalización (ISO) el 12 de agosto de 2011, reemplazando al anterior C++03. A partir del 18 de agosto de 2014 fue sustituido por la versión C++14 y más tarde por C++17. El nombre sigue la tradición de denominar a las versiones del lenguaje C++ a partir de la fecha de publicación, aunque su nombre original fue C++0x debido a que esperaba ser publicada antes de 2010.

A pesar de que uno de los objetivos era hacer los cambios en las librerías en lugar de hacerlo en el núcleo del lenguaje, C++11 añade algunas cosas al núcleo. Algunas áreas del lenguaje que fueron significativamente mejoradas como el soporte multihilo, soporte para la programación genérica, inicialización uniforme y el rendimiento. La Librería Estándar de C++ también recibió numerosos cambios, incorporando la mayoría de las bibliotecas definidas en el documento C++ Technical Report 1 (TR1), con la excepción de la biblioteca de funciones matemáticas especiales.

El borrador más parecido al C++11 publicado es el N3337 del 16 de enero de 2012, el cual realiza solo algunas correcciones editoriales al estándar.

Directivas de diseño

En el desarrollo de cada utilidad del nuevo estándar, el comité ha aplicado algunas directivas:

  • Mantener la estabilidad y la compatibilidad con C++98 y posiblemente con C.
  • Preferir la introducción de nuevas características a través de la biblioteca estándar, en lugar de modificar el núcleo del lenguaje.
  • Preferir los cambios que puedan hacer evolucionar las técnicas de programación.
  • Mejorar C++ para facilitar el diseño de sistemas y bibliotecas, en vez de introducir nuevas características solamente útiles a aplicaciones específicas.
  • Incrementar la seguridad de los tipos de datos suministrando alternativas más seguras a las técnicas inseguras anteriores.
  • Incrementar el rendimiento y la habilidad de trabajar directamente con hardware.
  • Proveer soluciones apropiadas para los problemas del mundo real.
  • Implementar el principio de zero-overhead (soporte adicional requerido por algunas utilidades debe ser usado solo si la utilidad es usada).
  • Hacer que C++ sea más fácil de enseñar y aprender sin la remoción de cualquier utilidad necesaria por los programadores expertos.

La atención a los principiantes es muy importante porque ellos siempre serán la mayoría entre los programadores, y porque muchos principiantes no intentarían ampliar su conocimiento de C++, limitándose ellos mismos a operar en los aspectos del lenguaje en el que están especializados. Adicionalmente, considerando la vastedad de C++ y de su uso (incluyendo áreas de aplicación y estilos de programación), incluso los programadores más experimentados pueden convertirse en principiantes en un nuevo paradigma de programación.

Extensiones al núcleo del lenguaje

Una función del comité de C++ es el desarrollo del núcleo del lenguaje. Las áreas del núcleo del lenguaje que fueron significativamente mejoradas incluyen el soporte multithreading (multihilo), el soporte de programación genérica, la inicialización uniforme, y mejoras del rendimiento.

Para los propósitos de este artículo, las características y los cambios del núcleo del lenguaje son agrupadas en 4 secciones generales:

Algunas características podrían entrar en múltiples grupos, pero solo son mencionadas en el grupo que primariamente representa esa característica.

Mejoras al rendimiento en tiempo de ejecución

Estas características del lenguaje existen primariamente para proporcionar un cierto tipo de beneficio en el rendimiento, tanto de la memoria como de la velocidad cómputo.

  • Referencias rvalue y los move constructor
  • Expresiones constantes generalizadas
  • Modificación a la definición de plain old data

Referencias rvalue y los move constructor

En el C++03 (y anteriores), los temporales, llamados "rvalues" pues a menudo se encuentran en el lado derecho de una asignación, fueron pensados para nunca ser modificables - justo como en C (y eran considerados ser indistinguibles de los tipos const T&) - aunque en algunos casos los temporales habrían podido ser modificados, e incluso era considerados ser un útil agujero de escape (loophole) (para el anterior, ver Sutter, Alexandrescu "C++ coding standards" #15). C++11 agrega un nuevo tipo de referencia no-constante llamado una referencia rvalue, identificada por T&&. Esto refiere a los temporales en que se permite que sean modificados después de que son inicializados, con el propósito de permitir la "semántica del movimiento" (move semantics).

Un problema de rendimiento crónico con el C++03 son las costosas e innecesarias copias profundas que pueden suceder implícitamente cuando los objetos son pasados por valor. Para ilustrar el problema, considere que un std::vector<T> es, internamente, una envoltura (wrapper) alrededor de una tabla (array) de estilo C con un tamaño. Si un std::vector<T> temporal se crea en una función, solamente se puede almacenar creando un nuevo std::vector<T> y copiando todos los datos rvalue en él. Luego, el temporal y toda su memoria es destruido. (Por simplicidad, este argumento deja de lado la optimización del valor devuelto).

En el C++11, un "move constructor" del std::vector<T> que toma una referencia rvalue a un std::vector<T> puede simplemente copiar el puntero a la variable interna, de estilo C, fuera del rvalue en el nuevo std::vector<T>, entonces cambiar el puntero dentro del rvalue a null. Debido a que se puede reinicializar el puntero temporal, el objeto no se borra cuando se sale del ámbito (scope), y no es necesaria una copia profunda. Por otra parte, es una operación segura e invisible porque el temporal nunca se usará otra vez.

Las referencias de rvalue pueden proporcionar beneficios de rendimiento al código existente sin la necesidad realizar cualquier cambio fuera de la biblioteca estándar. El tipo del valor retornado de una función que retorna un std::vector<T> temporal no necesita ser cambiado explícitamente al std::vector<T> && para invocar al move constructor, pues los temporales son considerados automáticamente como rvalues. (Sin embargo, si std::vector<T> es la versión del C++03 sin un move constructor, después el copy constructor será invocado con un const std::vector<T>& como se hace normalmente, incurriendo en una significativa asignación de memoria).

Por razones de la seguridad, algunas restricciones son impuestas. Una variable nombrada nunca será considerada para ser un rvalue incluso si se ha declarado como tal; para conseguir un rvalue, la plantilla de función std::move<T> () debe ser usada. También, las referencias de rvalue solamente pueden ser modificadas bajo ciertas circunstancias, siendo pensado para ser usado primariamente con los move constructor.

Debido a la naturaleza de la fraseología de las referencias rvalue, y a una cierta modificación a la fraseología para las referencias del lvalue (referencias regulares), las referencias rvalue permiten a los desarrolladores proporcionar forwarding de funciones perfectos. Cuando se combina con las plantillas variadic, esta capacidad permite plantillas de función que pueden perfectamente remitir (forward) argumentos a otra función que tome esos argumentos particulares. Esto es más útil para forwarding de parámetros del constructor, para crear funciones de factoría que llamarán automáticamente al constructor correcto para los particulares argumentos.

Expresiones constantes generalizadas

El C++ siempre ha tenido el concepto de expresiones constantes. Estas son expresiones tales como 3+4 que darán siempre los mismos resultados, en tiempo de compilación y en tiempo de ejecución. Las expresiones constantes son oportunidades de optimización para los compiladores, y los compiladores frecuentemente las ejecutan en tiempo de compilación y luego ponen los resultados codificados directamente en el programa (hard coded). También, hay un número de lugares en donde la especificación del C++ requiere el uso de expresiones constantes. La definición de un arreglo requiere una expresión constante, y los valores del enumerador deben ser expresiones constantes.

Sin embargo, las expresiones constantes siempre han terminado cuando una llamada de función o un constructor de objeto sea encontrado. Así que una pieza de código tan simple como ésta es ilegal:

int dame_cinco() {return 5;} int algun_valor[dame_cinco() + 7]; // Crea un arreglo de 12 enteros. Ilegal en C++ 

Éste no es C++ legal, porque dame_cinco() + 7 no es una expresión constante. El compilador no tiene manera de saber si dame_cinco() es realmente constante en tiempo de ejecución. En teoría, esta función podía afectar a una variable global, llamar a otras funciones constantes de no tiempo de ejecución, etc.

C++11 introdujo la palabra clave constexpr (expresión constante), que permite al usuario garantizar que una función o un constructor de objeto es constante en tiempo de compilación. El ejemplo de arriba puede ser reescrito como sigue:

constexpr int dame_cinco() {return 5;} int algun_valor[dame_cinco() + 7]; // Crea un arreglo de 12 enteros. Legal en C++11 

Esto permite que el compilador entienda, y verifique, que dame_cinco es una constante en tiempo de compilación.

El uso del constexpr en una función impone limitaciones muy estrictas en lo que esa función puede hacer. Primero, la función debe tener un tipo de retorno que no sea void. En segundo lugar, el contenido de la función debe ser de la forma: return expresión. Tercero, la expresión debe ser una expresión de constante después de la sustitución del argumento. Esta expresión constante puede solamente llamar a otras funciones definidas como constexpr, o puede usar otras variables de datos de expresiones constantes. Por último, una función con esta etiqueta no puede ser llamada hasta que es definida en esta unidad de traducción (translation unit).

Las variables también pueden ser definidas como valores de expresiones constantes:

constexpr double aceleracion_de_gravedad = 9.8; constexpr double gravedad_lunar = aceleracion_de_gravedad / 6.0; 

Las variables de los datos de la expresión constante son implícitmente const. Solo pueden almacenar los resultados de expresiones constantes o de constructores de expresiones constantes.

Para construir valores de datos de expresión constante desde tipos definidos por el usurario, los constructores también pueden ser declarados con constexpr. Un constructor de expresión constante debe ser definido antes de su uso en la unidad de traducción, como con las funciones de expresión constante. Debe tener un cuerpo de función vacío. Debe inicializar a sus miembros con expresiones constantes. Los destructores para tales tipos deben ser triviales.

Para copiar tipos construidos constexpr también deben ser definidos como constexpr, para permitir que retornen por valor desde una función constexpr. Cualquier función miembro de una clase, tal como copy constructors, sobrecarga de operadores, etc, pueden ser declaradas como constexpr, siempre y cuando adapten la definición para expresiones constantes de función. Esto permite al compilador copiar clases en tiempo de compilación, realiza operaciones en ellas, etc.

Una función de expresión constante o un constructor puede ser llamado con parámetros que no sean constexpr. Justo como un literal de número entero constexpr puede ser asignado a una variable que no sea constexpr, así que una función constexpr también puede ser llamada con parámetros que no sean constexpr, y los resultados almacenados en variables que no sean constexpr. La palabra clave solo permite la posibilidad de constante de tiempo de compilación cuando todos los miembros de una expresión son constexpr.

Modificación a la definición de plain old data

En el C++03, una clase o struct debe seguir un número de reglas para que sea considerado un tipo plain old data (POD). Los tipos que cumplen esta definición producen layouts de objetos que son compatibles con C. Sin embargo, la definición en C++03 es innecesariamente estricta y hay buenas razones para permitir a más tipos cumplir la definición de POD [cita requerida]. C++11 relajó varias de las reglas [cita requerida].

Una clase/struct es considerada una POD si es trivial, de standard-layout, y si todos sus miembros no estáticos son POD.

Una clase o struct trivial se define como uno los siguientes:

  1. Tiene un constructor trivial por defecto. Éste puede usar la sintaxis de constructor por defecto (AlgunConstructor () = default;)
  2. Tiene constructores copy y move triviales, que pueden usar la sintaxis por defecto
  3. Tiene operadores de asignación copy y move triviales, los cuales pueden usar la sintaxis por defecto
  4. Tiene un destructor trivial, que no debe ser virtual

Una clase o struct es standard-layout, por definición, con tal que cumpla lo siguiente:

  1. No tenga funciones virtuales
  2. No tenga clases base virtuales
  3. No tenga clases base del mismo tipo que el primer miembro de datos definido no estático
  4. Todos sus miembros de datos no estáticos tienen el mismo control de acceso (público, privado, protegido)
  5. Todos sus miembros de datos no estáticos, incluyendo cualquiera en sus clases base, están en la misma clase en la jerarquía
  6. Las reglas antedichas también se aplican a todas las clases base y a todos los miembros de datos no estáticos en la jerarquía

Mejoras en el rendimiento del núcleo del lenguaje en tiempo de compilación

Plantilla Extern

En el C++03, el compilador debe instanciar una plantilla siempre que una plantilla especificada completamente es encontrada en una unidad de traducción. Si la plantilla es instanciada con el mismo tipo en muchas unidades de traducción, ésta puede aumentar dramáticamente el tiempo de compilación. No hay manera de prevenir esto en C++03, así que C++11 introdujo las declaraciones de plantilla extern, análogas a las declaraciones de datos extern.

C++03 tiene esta sintaxis para obligar al compilador a instanciar una plantilla:

template class std::vector<MiClase>; 

C++11 ahora proporciona este sintaxis:

extern template class std::vector<MiClase>; 

la cual le dice al compilador que no instancie la plantilla en esta unidad de traducción.

Mejoras en la usabilidad del núcleo del lenguaje

Estas características existen para el propósito primario de hacer el lenguaje más fácil usar. Estas pueden mejorar la seguridad de tipo, minimizar la repetición de código, hacer que el código erróneo sea menos probable, etc.

  • Inicializador de listas
  • Inicialización uniforme
  • Inferencia de tipos
  • Bucle for basado en rango
  • Funciones y expresiones lambda
  • Sintaxis alternativa de función
  • Mejora en la construcción de objetos
  • Override y final explícitos
  • Constante de puntero nulo
  • Enumeraciones fuertemente tipeadas
  • Paréntesis de ángulo del lado derecho (Right angle bracket)
  • Operadores de conversión explícita
  • Alias de plantillas
  • Uniones sin restricciones
  • Identificadores con significado especial

Inicializador de listas

C++03 heredó la característica del inicializador de lista de C. Un struct o un arreglo recibe una lista de argumentos en llaves cuadradas (corchetes), en el orden de las definiciones de los miembros en el struct. Estos inicializadores de listas son recursivos, así que pueden usarlos un arreglo de structs o un struct que contiene otros structs.

struct Objeto {  float primero;  int segundo; }; Objeto escalar = {0.43f, 10}; // Un objeto, con primero=0.43f y segundo=10 Objeto unArreglo[] = {{13.4f, 3}, {43.28f, 29}, {5.934f, 17}}; // Un arreglo con tres objetos 

Esto es muy útil para las listas estáticas o justo para inicializar un struct con un valor particular. C++ también proporciona constructores para inicializar un objeto, pero a menudo no son tan convenientes como el inicializador de lista. Sin embargo C++03 solo permite inicializar listas en los structs y las clases que se ajustan a la definición Plain Old Data (POD); C++11 extiende la inicialización de listas, así que pueden ser usadas para todas las clases incluyendo los contenedores estándar como el std::vector.

C++11 ata (bind) el concepto a una plantilla, llamada std::initializer_list. Esto permite que los constructores y otras funciones tomen inicializadores de lista como parámetros. Por ejemplo:

class ClaseDeSecuencia { public: ClaseDeSecuencia(std::initializer_list<int> list); }; 

Esto permite que ClaseDeSecuencia sea construida de una secuencia de números enteros, como en:

ClaseDeSecuencia alguna_variable = {1, 4, 5, 6}; 

Esta es una clase especial de constructor, llamada constructor inicializador de lista. Las clases con tal constructor son tratadas especialmente durante la inicialización uniforme (ver abajo)

La clase std::initializer_list<> es un tipo de biblioteca estándar C++11 de primera clase. Sin embargo, solo pueden ser inicialmente construidos estáticamente por el compilador de C++11 con el uso de la sintaxis {}. La lista puede ser copiada una vez construida, por lo que es solamente una copia-por-referencia. Una lista de inicializador es constante; una vez que la lista del inicializador es creada, sus miembros no pueden ser cambiados, ni los datos en esos miembros.

Debido a que el initializer_list es un verdadero tipo, puede ser usado en otros lugares además de los constructores de clase. Las funciones regulares pueden tomar tipos de listas inicializadas como argumentos. Por ejemplo:

void nombre_de_funcion(std::initializer_list<float> list); nombre_de_funcion({1.0f, -3.45f, -0.4f}); 

Los contenedores estándar también pueden ser inicializados de las maneras siguientes:

std::vector<std::string> v = { "xyzzy", "plugh", "abracadabra" }; std::vector<std::string> v{ "xyzzy", "plugh", "abracadabra" }; 

Inicialización uniforme

El C++03 tiene un número de problemas con los tipos de inicialización. Hay varias maneras de inicializar tipos, y no todas producen los mismos resultados cuando son intercambiadas. La sintaxis tradicional del constructor, por ejemplo, puede parecerse como una declaración de función, y deben tomarse medidas para asegurarse que la regla del parse más irritante no la confundirá como tales. Solamente los agregados y los tipos POD pueden ser inicializados con inicializadores agregados (usando SomeType var = {/*stuff*/};).

C++11 proporciona una sintaxis que permite la inicialización de tipo completamente uniforme que trabaja en cualquier objeto. Se expande en la sintaxis de inicializador de lista:

struct EstructuraBasica {  int x;  double y; }; struct EstructuraAlterna {  EstructuraAlterna(int x, double y) : x_{x}, y_{y} {} private:  int x_;  double y_; }; EstructuraBasica var1{5, 3.2}; EstructuraAlterna var2{2, 4.3}; 

La inicialización de var1 se comporta exactamente como si fuera una inicialización de agregado. Es decir, cada miembro de datos de un objeto, a su vez, será inicializado por copia con el correspondiente valor de la lista de inicialización. La conversión de tipo implícita será usada cuando se necesite. Si no existe ninguna conversión, o solo existe un estrechamiento de conversión, el programa está malformado. La inicialización de var2 invoca al constructor.

También se puede hacer lo siguiente:

struct CadenaDeIdentificacion {  std::string nombre;  int identificador; }; CadenaDeIdentificacion lee_cadena() {  return {"AlgúnNombre", 4}; // Note la falta de un tipo explícito } 

La inicialización uniforme no reemplaza la sintaxis de constructor. Todavía hay momentos en que es requerida la sintaxis de constructor. Si una clase tiene un constructor (TypeName(initializer_list<AlgunTipo>);), entonces toma prioridad sobre otras formas de construcción, a condición de que la lista del inicializador se conforme al tipo de constructor de secuencia. La versión C++11 del std::vector tiene un constructor de lista de inicialización para su tipo de plantilla. Esto significa que el siguiente código:

std::vector<int> el_vector{4}; 

llamará al constructor de la lista del inicializador, no el constructor del std::vector que toma un solo parámetro de tamaño y crea el vector con ese tamaño. Para acceder al último constructor, el usuario necesitará usar directamente la sintaxis de constructor estándar.

Inferencia de tipo

En el C++03 (y en C), el tipo de una variable debe ser explícitamente especificado para poder usarlo. Sin embargo, con el advenimiento de los tipos de plantilla y técnicas de metaprogramación de plantillas, puede que expresar el tipo de algo no sea fácil, particularmente cuando se trata de definir bien el valor de retorno de una función. También es difícil almacenar valores intermediarios en variables, y posiblemente se requerirá conocer las partes internas de una biblioteca de metaprogramación particular.

C++11 permite que esto sea mitigado de dos maneras. Primero, la definición de una variable con una inicialización explícita puede usar la palabra clave auto. Esto crea una variable del tipo específico del inicializador:

auto algun_extraño_tipo_llamable = boost::bind(&alguna_funcion, _2, _1, algun_objeto); auto otra_variable = 5; 

El tipo algun_extraño_tipo_llamable es simplemente lo que la plantilla particular de la función override de boost::bind retorna para esos argumentos particulares. Este tipo es fácilmente determinado por procedimiento por el compilador como parte de sus trabajos de análisis semántico, pero no es fácil de determinar por inspección por el usuario.

El tipo otra_variable también está bien definido, pero es más fácil de determinar por el usuario. Es un int, el cual es el mismo tipo que el literal de número entero.

Adicionalmente, la palabra clave decltype puede ser usada para determinar el tipo de una expresión en tiempo de compilación. Por ejemplo:

int algun_entero; decltype(algun_entero) otra_variable_entera = 5; 

Esto es más útil conjuntamente con auto, puesto que el tipo de una variable auto es solo conocido por el compilador. Sin embargo, el decltype también puede ser muy útil para las expresiones en el código que hacen un fuerte uso de sobrecarga de operador y de tipos especializados.

auto es también útil para reducir la verbosidad del código. Por ejemplo, en vez de escribir

for (std::vector<int>::const_iterator iterador = mi_vector.cbegin(); iterador != mi_vector.cend(); ++iterador) 

el programador puede utilizar el más corto

for (auto iterador = mi_vector.cbegin(); iterador != mi_vector.cend(); ++iterador) 

Esta diferencia crece a medida que el programador comienza a anidar los contenedores, aunque en tales casos los typedefs son una buena manera de disminuir la cantidad de código.

El tipo denotado por el decltype puede ser diferente del tipo deducido por auto.

#include <vector> int main() {  const std::vector<int> v(1);  auto a = v[0]; // a tiene el tipo int  decltype(v[0]) b = 1; // b tiene el tipo const int&, el tipo de retorno de    // std::vector<int>::operator[](size_type) const  auto c = 0;  // c tiene el tipo int  auto d = c;  // d tiene el tipo int  decltype(c) e; // e tiene el tipo int, el tipo de la entidad llamada por c  decltype((c)) f = c; // f tiene el tipo int&, porque (c) es un lvalue  decltype(0) g; // g tiene el tipo int, porque 0 es un rvalue } 

Bucle for basado en rango

En el C++03, la iteración sobre los elementos de una lista requiere mucho código. Otras lenguajes como C# y Java tienen atajos que permitan escribir una simple declaración "foreach" que camina automáticamente por la lista desde el comienzo hasta el final.

C++11 agregó una característica similar. La declaración for permite una iteración fácil sobre una lista de elementos:

int mi_arreglo[5] = {1, 2, 3, 4, 5}; for (int &x : mi_arreglo) {  x *= 2; } 

Esta forma de for, llamada "for basado en rango", iterará sobre cada elemento en la lista. Trabajará para los arreglos de estilo C, inicializadores de listas, y cualquier tipo que tenga definida una función begin() y end() que retorne iteradores. Todos los contenedores de biblioteca estándar que tienen pares begin/end trabajarán con la sentencia for basada en rango.

Funciones lambda y expresiones

C++11 proporciona la capacidad de crear funciones anónimas, llamadas funciones lambda. Estas se definen como sigue:

[](int x, int y) { return x + y; } 

El tipo de retorno está implícito; devuelve el tipo de la expresión de retorno (decltype (x+y)). El tipo de retorno de una lambda puede ser omitido siempre y cuando todas las expresiones de retorno devuelven el mismo tipo.

Sintaxis alternativa de función

la sintaxis de declaración de una función estándar de C era perfectamente adecuada para el conjunto de características de este lenguaje. A medida que C++ evolucionó desde el C, mantuvo la sintaxis básica extendiéndola en caso necesario. Sin embargo, a medida que C++ llegó a ser más complicado, expuso un número de limitaciones, particularmente con respecto a declaraciones de funciones de plantilla. Lo siguiente, por ejemplo, no es permitido en C++03:

template<class Lhs, class Rhs>  Ret funcion_de_suma(const Lhs &lhs, const Rhs &rhs) {return lhs + rhs;} // Ret debe ser el tipo de lhs+rhs 

El tipo Ret es cualquier cosa que la adición de los tipos Lhs y Rhs produzca. Incluso con la ya mencionada funcionalidad C++11 del decltype, esto no es posible:

template<class Lhs, class Rhs>  decltype(lhs+rhs) funcion_de_suma(const Lhs &lhs, const Rhs &rhs) {return lhs + rhs;} // No es legal en C++11 

Esto no es C++ legal porque lhs y rhs todavía no se han definido; no serán identificadores válidos hasta después de que el parser haya analizado el resto del prototipo de la función.

Para solucionarlo, C++11 introdujo una nueva sintaxis de declaración de función, con el tipo de retorno al final:

template<class Lhs, class Rhs>  auto funcion_de_suma(const Lhs &lhs, const Rhs &rhs) -> decltype(lhs+rhs) {return lhs + rhs;} 

Esta sintaxis puede ser usada para declaraciones y definiciones de funciones más mundanas:

struct AlgunaEstructura {  auto nombre_de_funcion(int x, int y) -> int; }; auto AlgunaEstructura::nombre_de_funcion(int x, int y) -> int {  return x + y; } 

En este caso el uso de la palabra clave "auto" significa algo diferente de su uso en la deducción de tipo automática.

Mejora en la construcción de objetos

En C++03, a los constructores de una clase no se les permite llamar a otros constructores de esa clase; cada constructor debe construir todos sus miembros de clase por sí mismo o llamar a una función de miembro común, como los siguientes,

class AlgunTipo {  int numero; public:  AlgunTipo(int nuevo_numero) : numero(nuevo_numero) {}  AlgunTipo() : numero(42) {} }; 
class AlgunTipo {  int numero; private:  void Construct(int nuevo_number) { numero = nuevo_numero; } public:  AlgunTipo(int nuevo_numero) { Construct(nuevo_numero); }  AlgunTipo() { Construct(42); } }; 

Los constructores para las clases base no pueden ser expuestos directamente a las clases derivadas; cada clase derivada debe implementar constructores incluso si un constructor de clase base fuera apropiado. los miembros de datos no constantes de las clases no pueden ser inicializados en el sitio de la declaración de esos miembros. Solo pueden ser inicializados en un constructor.

El C++11 proporciona soluciones a todos estos problemas.

El C++11 permite a los constructores llamar a otros constructores pares (conocidos como delegación). Esto permite a los constructores usar el comportamiento de otro constructor con un mínimo de código añadido. Ejemplos de otros lenguajes similares a C++ que proporcionen la delegación son Java, C#, y D.

Esta sintaxis es como sigue:

class AlgunTipo {  int numero; public:  AlgunTipo(int nuevo_numero) : numero(nuevo_numero) {}  AlgunTipo() : AlgunTipo(42) {} }; 

Note que, en este caso, el mismo efecto habría podido ser alcanzado haciendo new_number un parámetro por defecto. Sin embargo, la nueva sintaxis permite que al valor por defecto (42) sea expresado en la implementación en vez de la interfaz - un beneficio para los mantenedores del código de la biblioteca puesto que los valores por defecto para los parámetros de la función son "horneados" para llamar sitios, mientras que la delegación del constructor permite que el valor sea cambiado usando la biblioteca sin la recompilación del código.

Esto viene con una advertencia: C++03 considera un objeto a ser construido cuando su constructor termine de ejecutarse, pero C++11 considera un objeto construido una vez que cualquier constructor termine su ejecución. Puesto que se permitirá ejecutar a múltiples constructores, esto significará que cada constructor delegado ejecutará en un objeto completamente construido de su propio tipo. Los constructores de clase derivados, ejecutarán después de que toda la delegación en sus clases base esté completa.

Para los constructores de la clase base, el C++11 permite a una clase especificar que los constructores de la clase base sean heredados. Esto significa que el compilador C++11 generará código para realizar la herencia, el forwarding de clase derivada a la clase base. Observe que esto es una característica de todo o nada; todos los constructores de esa clase base son forwarded o ningunos de ellos lo son. También, observe que hay restricciones para la herencia múltiple, de tal manera que los constructores de clase no pueden ser heredados a partir de dos clases que usen constructores con la misma firma. Ni puede existir un constructor en la clase derivada que tenga una firma igual en la clase base heredada.

la sintaxis es como sigue:

class ClaseBase { public:  ClaseBase(int valor); }; class ClaseDerivada : public ClaseBase { public:  using ClaseBase::ClaseBase; }; 

Para la inicialización de miembros, C++11 permite la siguiente sintaxis:

class AlgunaClase { public:  AlgunaClase() {}  explicit AlgunaClase(int nuevo_valor) : valor(nuevo_valor) {} private:  int valor = 5; }; 

Cualquier constructor de la clase inicializará el valor en 5, si el constructor no sobreescribe la inicialización con las propios. Así que el constructor vacío de arriba inicializará el valor como establece la definición de la clase, pero el constructor que toma un int, lo inicializará con el parámetro dado.

También puede usar la inicialización de constructor o uniforme, en vez de la inicialización de igualdad mostrada arriba.

Override y final explícitos

En C++03, es posible crear accidentalmente una nueva función virtual, cuando en realidad uno solo se prepuso un override de una función de la clase base. Por ejemplo:

struct Base {  virtual void alguna_funcion(float); }; struct Derivada : Base {  virtual void alguna_funcion(int); }; 

Por ejemplo, queremos diseñar Derivada::alguna_funcion para reemplazar la versión de la clase base. Pero, debido a que la función virtual tiene una firma diferente, en realidad crea una segunda función virtual. Esto es un problema común, particularmente cuando un usuario va a modificar la clase base.

C++11 proporciona una sintaxis para solucionar este problema.

struct Base {  virtual void alguna_funcion(float); }; struct Derivada : Base {  virtual void alguna_funcion(int) override; // Mal formado porque no hace un override de un método de la clase base }; 

El identificador especial override significa que el compilador comprobará la clase base para ver si hay una función virtual con esta firma exacta. Y si no la hay, el compilador producirá un error.

C++11 también agrega la capacidad de prevenir poder heredar clases o sobrecargar funciones específicas. Esto se consigue con el identificador especial final. Por ejemplo:

struct Base1 final { }; struct Derivada1 : Base1 { }; // Mal formado porque la clase base está marcada como final struct Base2 {  virtual void f() final; }; struct Derivada2 : Base2 {  void f(); // Mal formado porque la función virtual Base2::f está marcada como final }; 

En este ejemplo, la sentencia virtual void f() final; declara una nueva función virtual, pero también previene a las clases derivadas poder sobrecargarla. También tiene el efecto de prevenir, a las clases derivadas, de usar esa combinación particular de nombre de función y parámetros.

Observe que ni override ni final son palabras claves del lenguaje. Técnicamente son identificadores; solo ganan un significado especial cuando son usados en esos contextos específicos. En cualquier otra localización, pueden ser identificadores válidos.

Constante de puntero null

Únicamente para los propósitos de esta sección, cada ocurrencia de "0" significará "expresión constante que se evalúa a 0, que es del tipo entero int". En realidad, la expresión constante puede ser de cualquier tipo entero.

Desde el amanecer de C en 1972, la constante 0 ha tenido el doble papel de constante de número entero y de constante de puntero nulo. La ambigüedad inherente en el doble significado de 0 fue tratada en C por el uso del macro NULL del preprocesador, que comúnmente expande a ((void*)0) ó 0. C++ no adoptó el mismo comportamiento, permitiendo a 0 solamente como constante del puntero nulo. Esto interactúa mal con la sobrecarga de funciones:

void foo(char *); void foo(int); 

Si NULL está definido como 0 (lo usual en el caso del C++), la sentencia foo(NULL); llamará a foo(int), que casi con toda certeza no es lo que pensó el programador, y no es lo que sugiere una lectura superficial del código.

C++11 corrige esto introduciendo una nueva palabra clave para servir como constante inconfundible de puntero nulo: nullptr. Es del tipo nullptr_t, que es implícitamente convertible y comparable a cualquier tipo de puntero o tipo de puntero-a-miembro. No es implícitamente convertible o comparable a los tipos enteros, a excepción de bool. Mientras que la propuesta original especificó que un rvalue del tipo nullptr no debería ser convertible a bool, el grupo de trabajo del núcleo del lenguaje decidió que tal conversión sería deseable, para la consistencia con los tipos punteros regulares. Los cambios de redacción propuestos fueron votados unánimemente en el documento de trabajo en junio de 2008.[1]

Por razones de compatibilidad hacia atrás, 0 sigue siendo un constante de puntero nulo válida.

char *pc = nullptr; // OK int *pi = nullptr; // OK bool b = nullptr; // OK. b es false. int i = nullptr; // error foo(nullptr);  // invoca foo(char *), no foo(int); 

Enumeraciones de tipo estricto

En C++03, las enumeraciones no son de tipo seguro. Internamente, en realidad son números enteros, incluso cuando los tipos de la enumeración son distintos. Esto permite la comparación entre dos valores de diferentes tipos de enumeración. La única seguridad que C++03 proporciona es que un número entero o un valor de un tipo enum no se convierte implícitamente a otro tipo enum. Además, el tipo 'int' subyacente está definido por la implementación del compilador. Por lo tanto, el código que depende del tamaño de la enumeración no es portable. Por último, los valores de la enumeración tienen un ámbito definido por el ámbito que los encierra. Así, no es posible que dos enumeraciones separadas tengan nombres de miembro que emparejen.

C++11 permitirá una clasificación especial de la enumeración que no tiene ninguno de esos problemas. Esto es expresado usando la declaración enum class (enum struct también es aceptado como un sinónimo):

enum class Enumeracion {  Valor1,  Valor2,  Valor3 = 100,  Valor4 /* = 101 */ }; 

Esta enumeración es de tipo seguro; los valores de enum class no son convertidos implícitamente a números enteros. Por lo tanto, no pueden ser comparados con números enteros (la expresión Enumeracion::Valor4 == 101 da un error del compilador).

El tipo subyacente de los miembros de las clases de enum no estará predefinido. Por defecto, como en el caso anterior, es int, pero puede ser especificado explícitamente a un tipo diferente:

enum class Enumeracion2 : unsigned int {Valor1, Valor2}; 

El ámbito de la enumeración también está definido como el ámbito del nombre de la enumeración. Usando los nombres de enumerador requiere explícitamente el uso de ámbitos. Valor1 es indefinido, pero Enumeracion2::Valor1 está definido.

Adicionalmente, C++11 permitirá que las enumeraciones estándar proporcionen un ámbito explícito así como la definición del tipo subyacente:

enum Enumeracion3 : unsigned long {Valor1 = 1, Valor2}; 

Los nombres del enumerador son definidos en el ámbito de la enumeración (Enumeración3::Valor1), pero para la compatibilidad hacia atrás, los nombres del enumerador también son colocados en el ámbito de encerrado.

La declaración de enums también es posible en C++11. Previamente, los tipos de enum no podían ser declarados porque el tamaño de la enumeración depende de la definición de sus miembros. Siempre que el tamaño de la enumeración sea especificado implícita o explícitamente, puede ser declarado lo siguiente:

enum Enumeracion1;  // Ilegal en C++ y C++11; el tipo subyacente no puede ser determinado enum Enumeracion2 : unsigned int; // Legal en C++11, el tipo subyacente está especificado explícitamente enum class Enumeracion3;  // Legal en C++11, el tipo subyacente es int enum class Enumeracion4 : unsigned int; // Legal en C++11. enum Enumeracion2 : unsigned short; // Ilegal en C++11, porque Enumeracion2 estaba declarado con un tipo subyacente diferente. 

Paréntesis de ángulo del lado derecho

El parser del C++03 define “>>” como el operador de desplazamiento derecho en todos los casos. Sin embargo, con declaraciones jerarquizadas de plantilla, hay una tendencia para que el programador descuide poner un espacio entre los dos paréntesis de ángulo derecho, causando por lo tanto un error de sintaxis del compilador.

C++11 mejorará la especificación del parser de modo que múltiples paréntesis de ángulo derechos sean interpretados, donde sea razonable, como cierre de la lista de argumentos de la plantilla. Esto puede ser sobreescrito usando paréntesis:

template<bool Prueba> class AlgunTipo; std::vector<AlgunTipo<1>2>> x1; // Interpretado como un std::vector de AlgunTipo<true> 2>, // lo cual NO es una sintaxis legal. 1 es true. std::vector<AlgunTipo<(1>2)>> x1; // Interpretado como un std::vector de AlgunTipo<false>, // Lo cual SÍ es una sintaxis legal en C++11. (1>2) es false. 

Operadores de conversión explícitos

C++03 agregó la palabra clave explicit como un modificador para prevenir que los constructores con un solo argumento fueran usados como operadores de conversión de tipo implícito. Sin embargo, esto no hace nada por los reales operadores de conversión. Por ejemplo, una clase puntero inteligente puede tener un operator bool() para permitir que actúe más como un puntero primitivo: si incluye esta conversión, puede ser probada con if(smart_ptr_variable) (el cual sería true si el puntero no fuera null y de lo contrario false). Sin embargo, esto también permite otras conversiones no intencionales. Puesto que el bool de C++ es definido como tipo aritmético, puede ser implícitamente convertido a los tipos entero o aún a los tipos flotantes, lo que permite las operaciones matemáticas que no fueron pensadas por el usuario.

En C++11, la palabra clave explicit ahora puede ser aplicada a los operadores de conversión. Como con los constructores, previene el uso de funciones de conversión en conversiones implícitas. Sin embargo, contextos del lenguaje que específicamente requieren valor boleano, (las condiciones de sentencias if y en bucles, tan bien como operandos en operadores lógicos), como en conversiones explícitas y por lo tanto pueden usar a un operador de conversión bool.

Alias de plantillas

En C++03, solo es posible definir un typedef como un sinónimo para otro tipo, incluyendo un sinónimo para una especialización de plantilla con todos los argumentos reales de la plantilla especificados. No es posible crear una plantilla de typedef como la siguiente:

template <typename Primero, typename Segundo, int tercero> class AlgunTipo; template <typename Segundo> typedef AlgunTipo<OtroTipo, Segundo, 5> TypedefName; // Ilegal en C++ 

Esto no compilará.

C++11 agregará esta capacidad con la siguiente sintaxis:

template <typename Primero, typename Segundo, int tercero> class AlgunTipo; template <typename Segundo> using TypedefName = AlgunTipo<OtroTipo, Segundo, 5>; 

En C++11, la sintaxis también puede ser usada para alias de tipos:

typedef void (*Tipo)(double); // Viejo estilo using Tipo = void (*)(double); // Nueva sintaxis introducida 

Uniones sin restricción

En C++03 hay restricciones en qué tipos de objetos pueden ser miembros de una unión. Por ejemplo, las uniones no pueden contener objetos que definan a un constructor no trivial. C++11 suprime algunas de estas restricciones.[2]

Éste es un simple ejemplo de una unión permitida en C++:

//for placement new #include <new> struct Punto {  Punto() {}  Punto(int x, int y): x_(x), y_(y) {}  int x_, y_; }; union U {  int z;  double w;  Punto p;  // Ilegal en C++; Punto tiene un constructor no trivial. Sin embargo, esto es legal en C++11.  U() { new( &p ) Punto(); } // Funciones miembro no triviales son definidas implícitamente por una unión;    // Si se requiere, en su lugar, ellas son borradas para forzar una definición manual. }; 

Los cambios no romperán ningún código existente puesto que solamente se relajan las reglas actuales.

Identificadores con significado especial

Los identificadores override y final tienen un significado especial solo cuando son usados en un cierto contexto, de lo contrario pueden usarse como identificadores normales.

Mejoras en la funcionalidad del núcleo del lenguaje

Estas características permiten al lenguaje hacer cosas que eran previamente imposibles, excesivamente verbosas, o requerían bibliotecas no portables.

  • Plantillas variadic
  • Nuevos literales de string
  • Literales definidos por el usuario
  • Modelo de memoria multitarea
  • Almacenamiento local de hilos
  • Miembros de funciones especiales defaulted y deleted explícitos
  • Tipo long long int
  • Aserciones estáticas
  • Permitir a sizeof trabajar en miembros de clase sin un objeto explícito
  • Permitir implementaciones de recolección de basura

Plantillas de Variadic

En C++11, las plantillas pueden tomar números variables de parámetros. Esto también permite la definición de funciones variadic tipo seguro.

Nuevos literales de string

C++03 ofrece dos clases de literales de string (cadena). La primera clase, contenida dentro de comillas dobles, produce un arreglo terminado en null de tipo const char. La segunda clase, definida como L"", produce un arreglo terminado en null de tipo const wchar_t, donde wchar_t es un carácter ancho. Ninguno de los tipos literales ofrece soporte para literales de string con UTF-8, UTF-16, o cualquier otra clase de codificaciones de Unicode.

Con el propósito de realzar en los compiladores de C++ el soporte de unicode, la definición del tipo char ha sido modificada para que tenga por lo menos el tamaño necesario para almacenar una codificación UTF-8 de ocho bits y lo suficientemente grande como para contener cualquier miembro del juego de caracteres de ejecución básicos del compilador. Anteriormente estaba definida solo como esto último.

Además de este cambio en la definición de char, C++11 soportará tres codificaciones de Unicode: UTF-8, UTF-16, y UTF-32, y añadirá dos nuevos tipos de carácter: char16_t y char32_t. Estos están diseñados para almacenar UTF-16 y UTF-32 respectivamente.

El ejemplo siguiente muestra cómo crear literales string para cada una de estas codificaciones:

u8"I'm a UTF-8 string." u"This is a UTF-16 string." U"This is a UTF-32 string." 

El tipo del primer string es el habitual const char[]. El tipo del segundo string es const char16_t[] y el tipo del tercero es const char32_t[].

Al construir literales de string unicode, a menudo es útil insertar códigos de unicode directamente. Para ello, C++11 permitirá la siguiente sintaxis:

u8"This is a Unicode Character: \u2018." u"This is a bigger Unicode Character: \u2018." U"This is a Unicode Character: \u2018." 

El número después del \u es un número hexadecimal; sin necesidad del prefijo 0x. El identificador \u representa un código de unicode de 16 bits; para insertar un código de 32 bits, se usa \U y un número hexadecimal de 32 bits. Solamente se admiten códigos válidos de Unicode. Por ejemplo, los valores en el intervalo U+D800-U+DFFF están prohibidos, pues están reservados para los pares sustitutos en las codificaciones UTF-16.

A veces también es útil evitar secuencias de escape de string manuales, particularmente al usar literales de archivos XML, lenguajes de scripting, o de expresiones regulares. C++11 proporcionará un literal de cadena raw:

R"(The String Data \ Stuff " )" R"delimiter(The String Data \ Stuff " )delimiter" 

En el primer caso, todo entre "( y )" es parte del string. Los caracteres " y \ no necesitan secuencia de escape. En el segundo caso, el "delimiter( inicia la cadena, y solamente se termina al encontrar )delimiter". El delimiter puede ser cualquier literal de hasta 16 caracteres de longitud. Este no puede contener espacios, caracteres de control, o los caracteres "(", ")", o "\". El uso de este delimitador permite que el usuario tenga caracteres ")" dentro de literales de cadena raw. Por ejemplo, R"delimiter((a-z))delimiter" es equivalente a "(a-z)".[3]

Los literales de cadena raw pueden combinarse con los prefijos de literal ancho o con cualquiera de los prefijos de literal unicode:

u8R"XXX(I'm a "raw UTF-8" string.)XXX" uR"*(This is a "raw UTF-16" string.)*" UR"(This is a "raw UTF-32" string.)" 

Literales definidos por el usuario

C++03 proporciona un número de literales. Los caracteres "12.5" son un literal que es resuelto por el compilador como tipo double con el valor de 12.5. Sin embargo, la adición del sufijo "f", como en "12.5f", crea un valor del tipo float que contiene el valor 12.5. Los modificadores de sufijo para los literales son fijados por la especificación del C++, y el código de C++ no puede crear nuevos modificadores literales.

C++11 también incluirá la capacidad para que el usuario defina nuevas clases de modificantes literales que construyan objetos basados en string de caracteres que el literal modifique.

La transformación de los literales es redefinida en dos fases distintas: raw y cooked (crudo y cocinado). Un literal raw es una secuencia de caracteres de un cierto tipo específico, mientras que el literal cocinado es de un tipo separado. El literal 1234 de C++, como literal crudo, es esta secuencia de caracteres: '1', '2', '3', '4'. Como literal cocinado, es el número entero 1234. El literal 0xA de C++ en forma cruda es '0', 'x', 'A', mientras que en forma cocinada es el número entero 10.

Los literales pueden ser extendidos tanto en formas crudas y cocinadas, con la excepción de los literales de string, que solo se pueden procesar en forma cocinada. Esta excepción es debido al hecho de que los string tienen prefijos que afecten al significado y al tipo específicos de los caracteres en cuestión.

Todos los literales definidos por el usuario son sufijos; la definición de literales de prefijo no es posible.

Los literales definidos por el usuario que procesan la forma cruda del literal son definidos como sigue:

OutputType operator "" _suffix(const char *literal_string); OutputType some_variable = 1234_suffix; 

La segunda declaración ejecuta el código definido por la función literal definida por el usuario. A esta función se le pasa "1234" como un string de estilo C, así que tiene un terminador null.

Un mecanismo alternativo para procesar literales de número entero y punto flotante crudos es a través de una plantilla variadic:

template<char...> OutputType operator "" _suffix(); OutputType some_variable = 1234_suffix; OutputType another_variable = 2.17_suffix; 

Esto instancia la función de procesamiento literal como operator "" _suffix<'1', '2', '3', '4'>(). En esta forma, no hay carácter null terminal en el string. El propósito principal para hacer esto es utilizar palabra clave constexpr de C++11 y permitir al compilador que el literal sea transformado enteramente en tiempo de compilación, asumiendo que OutputType es un tipo constexpr construible y copiable, y la función de procesamiento literal es una función constexpr.

Para los literales numéricos, el tipo de literal cocinado es unsigned long long para literales enteros, o long double para los literales de punto flotante. (Nota: No hay necesidad de tipos entero con signo porque un literal con prefijo de signo es parseado como expresión que contiene el signo como operador de prefijo unario seguido del número sin signo). No hay forma de plantilla alternativa:

OutputType operator "" _suffix(unsigned long long); OutputType operator "" _suffix(long double); OutputType some_variable = 1234_suffix; // usa la primera función OutputType another_variable = 3.1416_suffix; // usa la segunda función 

Para los literales de string, de acuerdo con los prefijos de string previamente mencionados, son usados:

OutputType operator "" _suffix(const char * string_values, size_t num_chars); OutputType operator "" _suffix(const wchar_t * string_values, size_t num_chars); OutputType operator "" _suffix(const char16_t * string_values, size_t num_chars); OutputType operator "" _suffix(const char32_t * string_values, size_t num_chars); OutputType some_variable = "1234"_suffix; // Llama la versión de la const char * OutputType some_variable = u8"1234"_suffix; // Llama la versión de la const char * OutputType some_variable = L"1234"_suffix; // Llama la versión de la const wchar_t * OutputType some_variable = u"1234"_suffix; // Llama la versión de la const char16_t * OutputType some_variable = U"1234"_suffix; // Llama la versión de la const char32_t * 

No hay forma alternativa de plantilla. Los literales de carácter son definidos similarmente.

Modelo de memoria de multitarea

El comité estándar de C++ planea estandardizar el soporte para la programación multihilo.

Hay dos partes implicadas: La primera parte es la definición de un modelo de memoria que permitirá que múltiples hilos coexistan en un programa, y la definición del soporte para la interacción entre los hilos. La segunda parte será proporcionada vía facilidades de la biblioteca. (Ver la sección de este artículo C++11#Facilidades de hilos).

El modelo de memoria define cuando los múltiples hilos pueden tener acceso a la misma posición de memoria, y especifica cuando las actualizaciones por un hilo llegan a ser visibles a otros hilos.

Almacenamiento de hilo local

En un ambiente con multi hilo, es común que cada hilo tenga algunas variables únicas. Esto actualmente sucede para las variables locales de una función, pero no sucede para las variables globales y estáticas.

Para el estándar ha sido propuesto una nueva duración de almacenamiento de hilo local (thread-local), además de las existentes estático, dinámico y automático, (static, dynamic, automatic). El almacenamiento de hilo local será indicado por el especificador de almacenamiento thread_local.

Cualquier objeto que pudiera tener la duración de almacenamiento estático (es decir, perdurar durante toda la ejecución del programa) se le puede dar la duración de hilo local. Lo que se quiere es que como cualquier otra variable de duración estática, un objeto hilo local pueda ser inicializado usando un constructor y destruido usando un destructor.

Miembros de funciones especiales defaulted y deleted explícitos

En C++03, el compilador proporciona, para las clases que no lo proporcionan por sí mismas, un constructor por defecto (default), un constructor de copia, un operador de asignación de copia (operator=), y un destructor. El programador puede sobreescribir estos comportamientos por defecto definiendo versiones personalizadas. C++ también define a varios operadores globales (tales como operator= y operator new) que trabajan sobre todas las clases, y que el programador puede sobreescribir.

Sin embargo, hay poco control sobre la creación de estos comportamientos por defecto. Hacer una clase intrínsecamente no copiable, por ejemplo, requiere la declaración de un constructor de copia y de un operador de asignación privados y la no definición de ellos. El intentar usar estas funciones es una violación de la regla de una sola definición. Como no se requiere un mensaje de diagnóstico,[4]​ esto da lugar típicamente a un error del enlazador (linker).[cita requerida]

En el caso del constructor default, el compilador no generará un constructor por defecto si una clase es definida con cualquier constructor. Esto es útil en muchos casos, pero es también útil para poder tener constructores especializados y el de defecto generado por el compilador.

C++11 permitirá el default y delete explícito de estas funciones miembro especiales. Por ejemplo, el tipo siguiente declara explícitamente que está usando al constructor default:

struct SomeType {  SomeType() = default; // Declara explícitamente el constructor por defecto.  SomeType(OtherType value); }; 

Alternativamente, ciertas características pueden ser inhabilitadas explícitamente. Por ejemplo, el tipo siguiente es no copiable:

struct NonCopyable {  NonCopyable & operator=(const NonCopyable&) = delete;  NonCopyable(const NonCopyable&) = delete;  NonCopyable() = default; }; 

El especificador = delete puede ser usado para prohibir llamar cualquier función, lo cual puede ser usado para rechazar la llamada de una función de miembro con parámetros particulares. Por ejemplo:

struct NoInt { void f(double i); void f(int) = delete; }; 

Un intento de llamar a f() con un int será rechazado por el compilador, en vez de realizar una conversión silenciosa a double. Esto puede ser generalizado para rechazar la llamada de la función con cualquier tipo con excepción de doble, de la siguiente manera:

struct OnlyDouble {  void f(double d);  template<class T> void f(T) = delete; }; 

Tipo long long int

En C++03, el más grande tipo entero es long int. Está garantizado que tenga por lo menos tantos bits usables como int. Esto resultaba en que long int tuviera un tamaño de 64 bits en algunas implementaciones populares y 32 bits en otras. Para abordar este problema, C++11 agrega un nuevo tipo entero long long int. Está garantizado que sea por lo menos tan grande como un long int, y que tenga no menos de 64 bits. El tipo fue originalmente introducido al C estándar con C99, y la mayoría de los compiladores de C++ ya lo soportan como extensión.[5][6]

Aserciones estáticas

C++03 proporciona dos métodos para probar aserciones: el macro assert y la directiva de preprocesador #error. Sin embargo, ninguno es apropiado para el uso en plantillas: el macro prueba la aserción en tiempo de ejecución, mientras que la directiva del preprocesador prueba la aserción durante el preprocesamiento, que sucede antes de la instanciación de las plantillas. Ninguno es apropiado para probar las propiedades que son dependientes de parámetros de plantillas.

La nueva utilidad introduce una nueva manera de probar aserciones en tiempo de compilación, usando la nueva palabra clave static_assert. La declaración asume la siguiente forma:

static_assert (constant-expression, error-message); 

Aquí están algunos ejemplos de cómo puede ser usado el static_assert:

static_assert ((GREEKPI > 3.14) && (GREEKPI < 3.15), "GREEKPI is inaccurate!"); 
template<class T> struct Check {  static_assert (sizeof(int) <= sizeof(T), "T is not big enough!"); }; 

Cuando la expresión constante es false el compilador produce un mensaje de error. El primer ejemplo representa una alternativa a la directiva de preprocesador #error, en contraste, en el segundo ejemplo la aserción es chequeada en cada instanciación de la clase de plantilla Check.

Las aserciones estáticas también son útiles fuera de las plantillas. Por ejemplo, una implementación de un algoritmo pudiera depender de que el tamaño de un long long fuera más grande que un int, algo que el estándar no garantiza. Tal asunción es válida en la mayoría de los sistemas y de los compiladores, pero no todos.

Permite a sizeof trabajar en miembros de clases sin un objeto explícito

En C++03, el operador sizeof puede ser usado en tipos y objetos. Pero no puede ser usado para hacer lo siguiente:

struct SomeType { OtherType member; }; sizeof(SomeType::member); // No trabaja en C++03. Válido con C++11 

Esto permite en C++11 retornar el tamaño de OtherType. C++03 no permite esto, así que es un error de compilación.

Permite implementaciones con recolección de basura

La implementación define si los objetos dinámicamente asignados que se vuelvan inalcanzables son reclamados automáticamente.

Cambios en la biblioteca estándar de C++

Un número de nuevas características serán introducidas en la biblioteca estándar del C++11. Muchos de estas características pueden ser implementadas bajo el estándar actual, pero algunas dependen, en mayor o menor medida, en nuevas características del núcleo de C++11.

Una gran parte de las nuevas bibliotecas son definidas en el C++ Technical Report 1 (Reporte Técnico 1 de C++) (llamado TR1), publicado en 2005. Están disponibles actualmente varias implementaciones completas y parciales del TR1 usando el namespace std::tr1. Para C++11 serán movidas al namespace std. Sin embargo, a medida que las características del TR1 son llevadas a la biblioteca estándar de C++11, cuando sea apropiado, éstas son actualizadas con características del lenguaje de C++ que no estaban disponibles en la versión inicial del TR1. También, pueden ser mejoradas con las características que eran posibles debajo el C++03, pero no eran parte de la especificación original del TR1.

El comité se prepone crear un segundo reporte técnico (llamado TR2) después de que esté completa la estandardización de C++11. Las propuestas de biblioteca que no estén listas para C++11 serán puestas en el TR2 u otros reportes técnicos.

Las siguientes propuestas están en curso para el C++11.

  • Actualizaciones a los componentes de la biblioteca estándar
  • Facilidades de hilos
  • Tipos tuple
  • Tablas hash
  • Expresiones regulares
  • Apuntadores inteligentes de propósito general
  • Facilidad de número aleatorio extensible
  • Referencia de envoltorio (wrapper)
  • Envoltorios polimórficos para objetos de funciones
  • Características de tipo para metaprogramación
  • Método uniforme para computar el tipo de retorno de objetos de funciones

Actualizaciones a los componentes de la biblioteca estándar

C++11 ofrece un número de nuevas características de lenguaje de las cuales se pueden beneficiar los actuales componentes de la biblioteca estándar. Por ejemplo, la mayoría de los containers (contenedores) de la biblioteca estándar pueden beneficiarse en la referencia Rvalue basada en el soporte del move constructor, tanto para mover rápidamente contenedores pesados alrededor, como para mover el contenido de esos contenedores a nuevas localizaciones de memoria. Los componentes de la biblioteca estándar serán actualizados con las nuevas características de lenguaje C++11 cuando sea apropiado. Estas incluyen, pero no se limitan necesariamente a:

  • Referencias Rvalue y el asociado soporte para move
  • Soporte para los tipos de caracteres Unicode de las unidades de codificación UTF-16, y UTF-32
  • Plantillas variadic (acopladas con las referencias de Rvalue para permitir forwarding perfecto)
  • Expresiones constantes en tiempo de compilación
  • Decltype
  • Operadores de conversión explícitos
  • Funciones Default/Deleted

Adicionalmente, ha pasado mucho tiempo desde que C++ fue estandardizado. Se ha escrito una gran cantidad de código usando la biblioteca estándar; esto ha revelado porciones de las bibliotecas estándar que podrían usar alguna mejora. Entre las muchas áreas de mejoras que son consideradas son los allocators de la biblioteca estándar. Un nuevo modelo basado en ámbito (scope) de allocators será incluido en el C++11 para complementar el modelo actual.

Facilidades de hilos

Mientras que el lenguaje C++11 proporcionará un modelo de memoria que soporta hilos (threading), el soporte primario para usar realmente hilos vendrá con la biblioteca estándar del C++11.

Será proporcionada una clase de tipo hilo (std::thread). Para correr el nuevo hilo, esta clase tomará un objeto función y opcionalmente una serie de argumentos. Será posible hacer que un hilo se detenga hasta que otro hilo en ejecución termine, proporcionando soporte de thread joining a través de la función de miembro std::thread::join(). De ser posible, también será proporcionado el acceso a los objetos nativos de hilo subyacentes para las operaciones específicas de la plataforma, por medio de la función de miembro std::thread::native_handle().

Para la sincronización entre los hilos, serán agregadas a la biblioteca mutexes apropiados (std::mutex, std::recursive_mutex, etc) y variables de condición (std::condition_variable y std::condition_variable_any). Esto será accesible con locks RAII (std::lock_guard y std::unique_lock) y algoritmos de bloqueo (locking) para fácil uso.

Para el trabajo de bajo nivel de alto rendimiento, a veces es necesario la comunicación entre los hilos sin el overhead de los mutexes. Esto es alcanzado usando operaciones atómicas en localizaciones de memoria. Estas pueden opcionalmente especificar las restricciones de visibilidad de memoria mínimas requeridas para una operación. Las barreras de memoria explícitas también pueden ser usadas para este propósito.

La biblioteca de hilo del C++11 también incluirá futuros y promesas para pasar resultados asincrónicos entre los hilos, y el std::packaged_task para envolver (wrapping) una llamada de función que puede generar tal resultado asincrónico. La propuesta de futuros fue criticada porque carece de una manera de combinar futuros y comprobar la terminación de un interior de una promesa dentro de un conjunto de promesas.[7]

Otras facilidades de hilo de alto nivel tales como thread pools han sido remitidas a un futuro informe técnico del C++. No serán una parte de C++11, pero su eventual implementación es esperada a ser construida enteramente en el tope de las características de la biblioteca de hilos.

La nueva facilidad std::async facility proporciona un método conveniente de correr tareas y de atarlas a un std::future. El usuario puede elegir si la tarea debe correr asincrónicamente en un hilo separado, o sincrónicamente en un hilo que espere por el valor. Por defecto la implementación puede elegir, lo que proporciona una manera fácil de tomar ventaja de la concurrencia del hardware sin la sobresubscripción (oversubscription), y proporciona algunas de las ventajas de un thread pool para los usos simples.

Tipos tuple

Los tuples son colecciones compuestas por los objetos heterogéneos de dimensiones pre-arregladas. Un tuple puede ser considerado una generalización de un miembro de estructura de las variables.

La versión C++11 del tuple del TR1 se beneficiará de las características C++11 como plantillas variadic. La versión TR1 requería un máximo número de tipos de contenedor definido por la implementación, y requería una sustancial cantidad de trucos de macro para implementarse razonablemente. Por contraste, la implementación de la versión C++11 no requiere ningún número máximo de tipos definidos explícitamente por la implementación. Aunque los compiladores casi ciertamente tendrán una profundidad interna máxima de recursión para la instanciación de plantillas (lo cual es normal), la versión de tuples de C++11 no expondrá este valor al usuario.

Usando plantillas variadic, la declaración de clase tuple se ve como sigue:

template <class ...Types> class tuple; 

Un ejemplo de la definición y uso del tipo tuple:

typedef std::tuple <int, double, long &, const char *> test_tuple; long lengthy = 12; test_tuple proof (18, 6.5, lengthy, "Ciao!"); lengthy = std::get<0>(proof); // Asigna a 'lengthy' el valor 18. std::get<3>(proof) = " Beautiful!"; // Modifica el cuarto elemento del tuple. 

Es posible crear el tuple proof sin la definición de su contenido, pero solamente si los tipos de elementos del tuple poseen constructores por defecto. Por otra parte, es posible asignar un tuple a otro tuple: si los tipos de los dos tuples son iguales, es necesario que cada tipo de elemento posea un constructor copy; de lo contrario, es necesario que cada tipo de elemento del tuple del lado derecho sea convertible al elemento correspondiente del tuple del lado izquierdo, o que el tipo de elemento correspondiente del tuple del lado izquierdo tenga un constructor conveniente.

typedef std::tuple <int , double, string > tuple_1 t1; typedef std::tuple <char, short , const char * > tuple_2 t2 ('X', 2, "Hola!"); t1 = t2 ; // Ok, los primeros dos elementos pueden ser convertidos,   // El tercer elemento puede ser construido desde un 'const char *'. 

Hay disponibles Los operadores relacionales (entre tuples con el mismo número de elementos), y hay disponibles dos expresiones para comprobar las características de un tuple (solamente durante la compilación):

  • std::tuple_size<T>::value retorna el número de elementos de el tuple T,
  • std::tuple_element<I, T>::type retorna el tipo del número de objeto I del tuple

Tablas hash

Una de las peticiones que más se repiten es la inclusión en la biblioteca estándar de C++ de las tablas hash (contenedores asociativos sin orden). No fue adoptada en el estándar actual solo debido a restricciones de tiempo. Aunque esta solución es menos eficiente que un árbol balanceado en el peor caso (en presencia de muchas colisiones), en muchas aplicaciones verdaderas se desempeña mejor.

Las colisiones serán manejadas solo a través de encadenamiento lineal porque el comité no considera oportuno estandardizar soluciones de direccionamiento abierto que introducen bastantes de problemas intrínsecos (sobre todo cuando es admitido el borrado de elementos). Para evitar los choques de nombres con las bibliotecas no estándar que desarrollaran sus propias implementaciones de la tabla hash, será utilizado el prefijo "unordered" en vez del "hash".

La nueva utilidad tendrá cuatro tipos de tablas hash, diferenciados en si aceptan o no elementos con la misma clave (claves únicas o claves equivalentes), y si mapean cada clave a un valor asociado.

Tipo de tabla hash Valores asociados Claves equivalentes
std::unordered_set   No   No
std::unordered_multiset   No   
std::unordered_map      No
std::unordered_multimap      No

Las nuevas clases satisfacen todos los requisitos de una clase container, y tienen todos los métodos necesarios para acceder elementos: insert, erase, begin, end.

Esta nueva utilidad no necesita ninguna extensión del núcleo del lenguaje de C++, solamente una pequeña extensión del encabezado <functional> y la introducción de encabezados <unordered_set> y <unordered_map>, (aunque la implementación tomará ventajas de varias características del lenguaje C++11). No son necesarios otros cambios a cualquier clase estándar existente, y no depende de ninguna de las otras extensiones de la biblioteca estándar.

Expresiones regulares

Muchas bibliotecas estandarizadas fueron creadas para manejar expresiones regulares. Puesto que el uso de estos algoritmos es muy común, la biblioteca estándar los incluirá usando todas las potencialidades de un lenguaje orientado a objetos.

La nueva biblioteca, definida en el nuevo encabezado <regex>, está hecha de un par de clases:

  • Las expresiones regulares son representadas por la instancia de la clase de plantilla std::regex;
  • Las ocurrencias son representadas por la instancia de la clase de plantilla std::match_results.

La función std::regex_search es usada para buscar, mientras que para ‘búsqueda y reemplazo’ es usada la función std::regex_replace, la cual retorna un nuevo string. Los algoritmos std::regex_search y std::regex_replace toman una expresión regular y un string y escriben las ocurrencias encontradas en la estructura std::match_results.

Aquí hay un ejemplo en el uso del std::match_results:

const char *reg_esp = "[ ,.\\t\\n;:]"; // List of separator characters. // this can be done using raw string literals: // const char *reg_esp = R"([ ,.\t\n;:])"; std::regex rgx(reg_esp); // 'regex' es una instancia de la clase de template    // 'basic_regex' con argumento de tipo 'char'. std::cmatch match; // 'cmatch' es una instancia de la clase de template    // 'match_results' con argumento de tipo 'const char *'. const char *target = "Unseen University - Ankh-Morpork"; // Identifies all words of 'target' separated by characters of 'reg_esp'. if( std::regex_search( target, match, rgx ) ) {  // If words separated by specified characters are present.  const size_t n = match.size();  for( size_t a = 0; a < n; a++ ) {  std::string str( match[a].first, match[a].second );  std::cout << str << "\n";  } } 

Note que se usan dobles barras inversas debido a que C++ usa la barra inversa simple como un carácter de escape. La característica raw string del C++11 pudiera usarse para evitar este problema.

La biblioteca <regex> no requiere ni la alteración de cualquier encabezado existente, (aunque los usará cuando sea apropiado), ni una extensión del núcleo del lenguaje.

Punteros inteligentes de propósito general

C++11 proporciona el std::unique_ptr, como también mejoras al std::shared_ptr y std::weak_ptr del TR1. std::auto_ptr es obsoleto.

Facilidad de número random extensible

La biblioteca estándar de C proporciona la capacidad de generar números pseudaleatorios (random) a través de la función rand. Sin embargo, el algoritmo es delegado enteramente al proveedor de la biblioteca. C++ heredó esta funcionalidad sin cambios, pero C++11 proporcionará un nuevo método para generar números pseudaleatorios.

La funcionalidad del número al azar (random) de C++11 está dividida en dos partes: un motor generador que contiene el estado del generador de número al azar y produce los números pseudaleatorios; y una distribución, que determina el rango y la distribución matemática del resultado. Estos dos son combinados para formar un objeto generador de números al azar.

A diferencia del rand estándar de C, el mecanismo del C++11 vendrá con tres algoritmos de motor generador, cada uno con sus propias fuerzas y debilidades:

Plantilla de clase Entero/Punto flotante Calidad Velocidad Tamaño del estado
linear_congruential Entero Mediana Mediana 1
subtract_with_carry Ambos Mediana Rápida 25
mersenne_twister Entero Buena Rápida 624

C++11 también proporcionará un número de distribuciones estándar: uniform_int_distribution, bernoulli_distribution, geometric_distribution, poisson_distribution, binomial_distribution, uniform_real_distribution, exponential_distribution, normal_distribution, y gamma_distribution

El generador y las distribuciones son combinados como en el ejemplo siguiente:

#include <random> #include <functional> std::uniform_int_distribution<int> distribution(0, 99); std::mt19937 engine; // Mersenne twister MT19937 auto generator = std::bind(distribution, engine); int random = generator(); // Genera una variable entera uniforme entre 0 y 99. int random2 = distribution(engine); // Genera otra muestra usando directamente los objetos distribution y engine. 

Referencia wrapper

Una referencia wrapper (envoltura) es obtenida de una instancia de la clase de plantilla reference_wrapper. Las referencias wrapper son similares a las referencias normales (‘&’) del lenguaje C++. Para obtener una referencia wrapper de cualquier objeto es usada la referencia de plantilla de función ref (para una referencia constante es usado cref).

Las referencias wrapper son útiles sobre todo para las plantillas de función, donde son necesarias las referencias a los parámetros en vez de a las copias:

// Esta función obtendrá una referencia al parámetro 'r' y lo incrementará. void f (int &r) { r++; } // Función de template. template<class F, class P> void g (F f, P t) { f(t); } int main() {  int i = 0 ;  g (f, i) ; // Es instanciado 'g<void (int &r), int>'   // entonces 'i' no será modificado.  std::cout << i << std::endl; // Salida -> 0  g (f, std::ref(i)); // Es instanciado 'g<void(int &r),reference_wrapper<int>>'   // entonces 'i' será modificado.  std::cout << i << std::endl; // Salida -> 1 } 

Esta nueva utilidad será agregada al encabezado existente <utility> y no necesita otras extensiones del lenguaje C++.

Envoltorios polimórficos para objetos de función

Los envoltorios polimórficos para los objetos de función son similares a los punteros de función en la semántica y la sintaxis, pero son menos fuertemente enlazados (tightly bound) y pueden referir indiscriminadamente cualquier cosa que puede ser llamada (punteros de función, punteros de miembro de función, o functors) cuyos argumentos son compatibles con las del envoltorio.

Con el ejemplo es posible entender sus características:

std::function<int (int, int)> func; // Creación de envoltorio (wrapper)     // usando la clase de plantilla 'function'. std::plus<int> add; // 'plus' es declarado como 'template<class T> T plus( T, T ) ;'   // entonces, 'add' es de tipo 'int add( int x, int y )'. func = &add; // OK - Los parámetros y el tipo de retorno son el mismo. int a = func (1, 2); // NOTA: si el envoltorio 'func' no se refiere a ninguna función,   // es lanzada la excepción 'std::bad_function_call'. std::function<bool (short, short)> func2 ; if(!func2) { // Verdadero porque a 'func2' todavía no se le ha asignado una función.  bool adjacent(long x, long y);  func2 = &adjacent ; // OK - Los parámetros y los tipos de retorno son convertibles.  struct Test {  bool operator()(short x, short y);  };  Test car;  func = std::ref(car); // 'std::ref' es una función de plantilla que retorna el envoltorio    // de función de miembro 'operator()' de struct 'car'. } func = func2; // OK - Los parámetros y los tipos de retorno son convertibles. 

La función de clase de plantilla será definida dentro del encabezado <functional>, y no requiere ningún cambio al lenguaje C++.

Type traits para metaprogramación

La metaprogramación consiste en crear un programa que crea o modifica otro programa (o a sí mismo). Esto puede suceder durante la compilación o durante la ejecución. El comité de estándares de C++ ha decidido introducir una biblioteca que permite la metaprogramación durante la compilación a través de plantillas.

Aquí hay un ejemplo de un meta-programa, usando el estándar actual de C++03: una recursión de instancias de plantillas para calcular exponentes enteros:

template<int B, int N> struct Pow {  // llamada recursiva y recombinación.  enum{ value = B*Pow<B, N-1>::value }; }; template< int B > struct Pow<B, 0> {  // ''N == 0'' condición de terminación.  enum{ value = 1 }; }; int quartic_of_three = Pow<3, 4>::value; 

Muchos algoritmos pueden operar en diferentes tipos de datos; Las plantillas de C++ soportan la programación genérica y hacen el código más compacto y útil. Sin embargo es común para los algoritmos necesitar información sobre los tipos de datos que son usados. Esta información puede ser extraída durante la instanciación de una clase de plantilla usando type traits.

El type traits puede identificar la categoría de un objeto y todas las características de una clase (o de un struct). Son definidos en el nuevo encabezado <type_traits>..

En el ejemplo siguiente está la función de plantilla 'elaborate' que, dependiendo de los tipos de datos dados, instanciará uno de los dos algoritmos propuestos (algorithm.do_it).

// Primera forma de operar. template< bool B > struct Algorithm {  template<class T1, class T2> static int do_it (T1 &, T2 &) { /*...*/ } }; // Segunda forma de operar. template<> struct Algorithm<true> {  template<class T1, class T2> static int do_it (T1, T2) { /*...*/ } }; // Instanciando 'elaborate' instanciará automáticamente la forma correcta de operar. template<class T1, class T2> int elaborate (T1 A, T2 B) {  // Usa la segunda forma solo si 'T1' es un entero y si 'T2' está  // en punto flotante, de lo contrario usa la primera forma.  return Algorithm<std::is_integral<T1>::value && std::is_floating_point<T2>::value>::do_it( A, B ) ; } 

A través del type traits, definido en encabezado <type_transform>, es también posible crear operaciones de transformación de tipos (static_cast y const_cast son insuficientes dentro de una plantilla).

Este tipo de programación produce un código elegante y conciso; sin embargo el punto débil de estas técnicas es la depuración: incómodo durante la compilación y muy difícil durante la ejecución del programa.

Método uniforme para computar el tipo de retorno de objetos de función

La determinación del tipo de retorno de un objeto de función de plantilla en tiempo de compilación no es intuitiva, particularmente si el valor de retorno depende de los parámetros de la función. Como un ejemplo:

struct Clear { int operator()(int); // El tipo del parámetro es double operator()(double); // igual al tipo de retorno. }; template <class Obj> class Calculus { public: template<class Arg> Arg operator()(Arg& a) const { return member(a); } private: Obj member; }; 

Instanciar la plantilla de clase Calculus<Clear>, el objeto de función de calculus tendrá siempre el mismo tipo de retorno que el objeto de función de Clear.. Sin embargo, dada la clase Confused de abajo:

struct Confused { double operator()(int); // El tipo del parámetro NO es int operator()(double); // igual al tipo de retorno. }; 

El intentar instanciar Calculus<Confused> causará que el tipo de retorno de Calculus no sea igual que el de clase Confused. El compilador puede generar advertencias acerca de la conversión desde int a double y viceversa.

El TR1 introduce, y C++11 adopta, la clase de plantilla std::result_of que permite que uno determine y que use el tipo de retorno de un objeto de función para cada declaración. El objeto CalculusVer2 usa al objeto std::result_of para derivar el tipo de retorno del objeto de función:

template< class Obj > class CalculusVer2 { public:  template<class Arg>  typename std::result_of<Obj(Arg)>::type operator()(Arg& a) const  {  return member(a);  } private:  Obj member; }; 

De esta manera en instancias del objeto de función CalculusVer2<Confused> no hay conversiones, advertencias, o errores.

El único cambio de la versión TR1 del std::result_of es que la versión TR1 permitía a una implementación fallar para poder determinar el tipo del resultado de una llamada de función. Debido a los cambios a C++ para soportar decltype, la versión C++11 del std::result_of ya no necesita estos casos especiales; son requeridas las implementaciones para computar un tipo en todos los casos.

Características eliminadas u obsoletas

Movidas a otro reporte:

  • Módulos
  • Tipos Decimales
  • Funciones Matemáticas Especiales

Pospuestas:

Características eliminadas u obsoletas

  • El término punto de secuencia, que será reemplazado al especificar que una operación es secuenciada después de otra, o que dos operaciones no son secuenciales[8]
  • Especificaciones de excepciones dinámicas. Con la palabra clave noexcept está disponible la especificación en tiempo de compilación de no excepción lanzando funciones (útil para optimización)
  • std::auto_ptr Reemplazado por std::unique_ptr.
  • Clases base de función objeto (std::unary_function, std::binary_function), adaptadores a punteros a funciones u adaptadores a punteros a miembros, clases binder.

Lectura adicional

Documentos del Comité de Estándar de C++

  • Doc No. 1401: Jan Kristoffersen (21 October 2002) Atomic operations with multi-threaded environments
  • Doc No. 1402: Doug Gregor (22 October 2002) A Proposal to add a Polymorphic Function Object Wrapper to the Standard Library
  • Doc No. 1403: Doug Gregor (8 November 2002) Proposal for adding tuple types into the standard library
  • Doc No. 1424: John Maddock (3 March 2003) A Proposal to add Type Traits to the Standard Library
  • Doc No. 1429: John Maddock (3 March 2003) A Proposal to add Regular Expression to the Standard Library
  • Doc No. 1449: B. Stroustrup, G. Dos Reis, Mat Marcus, Walter E. Brown, Herb Sutter (7 April 2003) Proposal to add template aliases to C++
  • Doc No. 1450: P. Dimov, B. Dawes, G. Colvin (27 March 2003) A Proposal to Add General Purpose Smart Pointers to the Library Technical Report (Revision 1)
  • Doc No. 1452: Jens Maurer (10 April 2003) A Proposal to Add an Extensible Random Number Facility to the Standard Library (Revision 2)
  • Doc No. 1453: D. Gregor, P. Dimov (9 April 2003) A proposal to add a reference wrapper to the standard library (revision 1)
  • Doc No. 1454: Douglas Gregor, P. Dimov (9 April 2003) A uniform method for computing function object return types (revision 1)
  • Doc No. 1456: Matthew Austern (9 April 2003) A Proposal to Add Hash Tables to the Standard Library (revision 4)
  • Doc No. 1471: Daveed Vandevoorde (18 April 2003) Reflective Metaprogramming in C++
  • Doc No. 1676: Bronek Kozicki (9 September 2004) Non-member overloaded copy assignment operator
  • Doc No. 1704: Douglas Gregor, Jaakko Järvi, Gary Powell (10 September 2004) Variadic Templates: Exploring the Design Space
  • Doc No. 1705: J. Järvi, B. Stroustrup, D. Gregor, J. Siek, G. Dos Reis (12 September 2004) Decltype (and auto)
  • Doc No. 1717: Francis Glassborow, Lois Goldthwaite (5 November 2004) explicit class and default definitions
  • Doc No. 1719: Herb Sutter, David E. Miller (21 October 2004) Strongly Typed Enums (revision 1)
  • Doc No. 1720: R. Klarer, J. Maddock, B. Dawes, H. Hinnant (20 October 2004) Proposal to Add Static Assertions to the Core Language (Revision 3)
  • Doc No. 1757: Daveed Vandevoorde (14 de enero de 2005) Right Angle Brackets (Revision 2)
  • Doc No. 1811: J. Stephen Adamczyk (29 April 2005) Adding the long long type to C++ (Revision 3)
  • Doc No. 1815: Lawrence Crowl (2 May 2005) ISO C++ Strategic Plan for Multithreading
  • Doc No. 1827: Chris Uzdavinis, Alisdair Meredith (29 August 2005) An Explicit Override Syntax for C++
  • Doc No. 1834: Detlef Vollmann (24 June 2005) A Pleading for Reasonable Parallel Processing Support in C++
  • Doc No. 1836: ISO/IEC DTR 19768 (24 June 2005) Draft Technical Report on C++ Library Extensions
  • Doc No. 1886: Gabriel Dos Reis, Bjarne Stroustrup (20 October 2005) Specifying C++ concepts
  • Doc No. 1891: Walter E. Brown (18 October 2005) Progress toward Opaque Typedefs for C++0X
  • Doc No. 1898: Michel Michaud, Michael Wong (6 October 2004) Forwarding and inherited constructors
  • Doc No. 1919: Bjarne Stroustrup, Gabriel Dos Reis (11 December 2005) Initializer lists
  • Doc No. 1968: V Samko; J Willcock, J Järvi, D Gregor, A Lumsdaine (26 February 2006) Lambda expressions and closures for C++
  • Doc No. 1986: Herb Sutter, Francis Glassborow (6 April 2006) Delegating Constructors (revision 3)
  • Doc No. 2016: Hans Boehm, Nick Maclaren (21 April 2002) Should volatile Acquire Atomicity and Thread Visibility Semantics?
  • Doc No. 2142: ISO/IEC DTR 19768 (12 de enero de 2007) State of C++ Evolution (between Portland and Oxford 2007 Meetings)
  • Doc No. 2228: ISO/IEC DTR 19768 (3 May 2007) State of C++ Evolution (Oxford 2007 Meetings)
  • Doc No. 2258: G. Dos Reis and B. Stroustrup Templates Aliases
  • Doc No. 2280: Lawrence Crowl (2 May 2007) Thread-Local Storage
  • Doc No. 2291: ISO/IEC DTR 19768 (25 June 2007) State of C++ Evolution (Toronto 2007 Meetings)
  • Doc No. 2336: ISO/IEC DTR 19768 (29 July 2007) State of C++ Evolution (Toronto 2007 Meetings)
  • Doc No. 2389: ISO/IEC DTR 19768 (7 August 2007) State of C++ Evolution (pre-Kona 2007 Meetings)
  • Doc No. 2431: SC22/WG21/N2431 = J16/07-0301 (2 October 2007), A name for the null pointer: nullptr
  • Doc No. 2432: ISO/IEC DTR 19768 (23 October 2007) State of C++ Evolution (post-Kona 2007 Meeting)
  • Doc No. 2437: Lois Goldthwaite (5 October 2007) Explicit Conversion Operators
  • Doc No. 2461: ISO/IEC DTR 19768 (22 October 2007) Working Draft, Standard for programming Language C++
  • Doc No. 2507: ISO/IEC DTR 19768 (4 February 2008) State of C++ Evolution (pre-Bellevue 2008 Meeting)
  • Doc No. 2565: ISO/IEC DTR 19768 (7 March 2008) State of C++ Evolution (post-Bellevue 2008 Meeting)
  • Doc No. 2597: ISO/IEC DTR 19768 (29 April 2008) State of C++ Evolution (pre-Antipolis 2008 Meeting)
  • Doc No. 2606: ISO/IEC DTR 19768 (19 May 2008) Working Draft, Standard for Programming Language C++
  • Doc No. 2798: ISO/IEC DTR 19768 (4 October 2008) Working Draft, Standard for Programming Language C++
  • Doc No. 2857: ISO/IEC DTR 19768 (23 March 2009) Working Draft, Standard for Programming Language C++
  • Doc No. 2869: ISO/IEC DTR 19768 (28 April 2009) State of C++ Evolution (post-San Francisco 2008 Meeting)
  • Doc No. 3014: Stephen D. Clamage (4 November 2009) AGENDA, PL22.16 Meeting No. 53, WG21 Meeting No. 48, 8–13 March 2010, Pittsburgh, PA
  • Doc No. 3082: Herb Sutter (13 March 2010) C++0x Meeting Schedule
  • Doc No. 3092: ISO/ISC DTR 19769 (26 March 2010) Working Draft, Standard for Programming Language C++
  • Doc No. 3126: ISO/ISC DTR 19769 (21 August 2010) Working Draft, Standard for Programming Language C++
  • Doc No. 3225: ISO/ISC DTR 19769 (27 November 2010) Working Draft, Standard for Programming Language C++
  • Doc No. 3242: ISO/ISC DTR 19769 (28 February 2011) Working Draft, Standard for Programming Language C++
  • Doc No. 3291: ISO/ISC DTR 19769 (5 April 2011) Working Draft, Standard for Programming Language C++
  • Doc No. 3290: ISO/ISC DTR 19769 (5 April 2011) FDIS, Standard for Programming Language C++

Artículos

  • Bjarne Stroustrup (1 de mayo de 2005). «The Design of C++0x: Reinforcing C++’s proven strengths, while moving into the future». C/C++ Users Journal. Consultado el 23 de marzo de 2009. 
  • Raffaele Rialdi (16 de septiembre de 2005). «Il futuro di C++ raccontato da Herb Sutter». Web Log di Raffaele Rialdi. Consultado el 23 de marzo de 2009. 
  • Danny Kalev (21 de julio de 2006). . InformIT. Archivado desde el original el 22 de octubre de 2012. Consultado el 23 de marzo de 2009. 
  • Danny Kalev (11 de julio de 2008). . InformIT. Archivado desde el original el 16 de septiembre de 2008. Consultado el 23 de marzo de 2009. 
  • Pete Becker (11 de abril de 2006). «Regular Expressions». Dr. Dobb's Portal. Consultado el 23 de marzo de 2009. 
  • Danny Kalev (10 de marzo de 2006). . InformIT. Archivado desde el original el 9 de abril de 2008. Consultado el 23 de marzo de 2009. 
  • Pete Becker (1 de mayo de 2005). «C++ Function Objects in TR: Getting from TR1 back to the Standard Library». Dr. Dobb's Portal. Consultado el 23 de marzo de 2009. 
  • Howard E. Hinnant, Bjarne Stroustrup, and Bronek Kozicki (10 de marzo de 2008). «A Brief Introduction to Rvalue References». The C++ Source. Consultado el 23 de marzo de 2009. 
  • «C++0x: The Dawning of a New Standard». DevX. 18 de agosto de 2008. Consultado el 23 de marzo de 2009. 
  • . Intel Software Network. 15 de abril de 2010. Archivado desde el original el 14 de agosto de 2011. 
  • Bjarne Stroustrup (August 2009). «No 'Concepts' in C++0x». accu.org. Consultado el 29 de junio de 2010. 
  • «Explicating the new C++ standard (C++0x), and its implementation in VC10». CodeProject.com. 8 de abril de 2010. Consultado el 13 de febrero de 2011. 

Véase también

Notas

Referencias

  1. Doc No. 2697: ISO/IEC DTR 19768 (15 June 2008) Minutes of WG21 Meeting 8–15 June 2008
  2. Doc No. 2544: Alan Talbot, Lois Goldthwaite, Lawrence Crowl, Jens Maurer (29 February 2008) Unrestricted unions
  3. Doc No. 3000: ISO/ISC DTR 19769 (9 November 2009) Working Draft, Standard for Programming Language C++
  4. ISO/IEC (2003). ISO/IEC 14882:2003(E): Programming Languages - C++ §3.2 One definition rule [basic.def.odr] para. 3
  5. http://gcc.gnu.org/onlinedocs/gcc/Long-Long.html
  6. http://msdn.microsoft.com/en-us/library/s3f49ktz(VS.80).aspx
  7. Milewski, Bartosz (3 de marzo de 2009). «Broken promises–C++0x futures». Consultado el 24 de enero de 2010. 
  8. Caves, Jonathan (4 de junio de 2007). «Update on the C++-0x Language Standard». Consultado el 25 de mayo de 2010. 

Enlaces externos

  • The C++ Standards Committee, comité encargado de los estándares del lenguaje C++, en inglés.
  • Bjarne Stroustrup's homepage, página personal del creador de C++, con información sobre la evolución del lenguaje, en inglés.
  • Boost C++ Libraries
  • Herb Sutter's blog coverage of C++0x
  • Anthony Williams' blog coverage of C++0x
  • A talk on C++0x given by Bjarne Stroustrup at the University of Waterloo
  • The State of the Language: An Interview with Bjarne Stroustrup (15 August 2008)
  • Wiki page to help keep track of C++ 0x core language features and their availability in compilers
  • Online C++11 standard library reference
  •   Datos: Q1061570

este, artículo, detectaron, varios, problemas, favor, edítalo, para, mejorarlo, podría, contener, información, desactualizada, texto, sigue, traducción, defectuosa, podría, difícil, entender, para, lectores, interesados, tema, este, aviso, puesto, septiembre, . En este articulo se detectaron varios problemas Por favor editalo para mejorarlo Podria contener informacion desactualizada El texto que sigue es una traduccion defectuosa Podria ser dificil de entender para lectores interesados en el tema Este aviso fue puesto el 7 de septiembre de 2017 C 11 es una version del lenguaje de programacion C estandar aprobado por la Organizacion Internacional de Normalizacion ISO el 12 de agosto de 2011 reemplazando al anterior C 03 A partir del 18 de agosto de 2014 fue sustituido por la version C 14 y mas tarde por C 17 El nombre sigue la tradicion de denominar a las versiones del lenguaje C a partir de la fecha de publicacion aunque su nombre original fue C 0x debido a que esperaba ser publicada antes de 2010 A pesar de que uno de los objetivos era hacer los cambios en las librerias en lugar de hacerlo en el nucleo del lenguaje C 11 anade algunas cosas al nucleo Algunas areas del lenguaje que fueron significativamente mejoradas como el soporte multihilo soporte para la programacion generica inicializacion uniforme y el rendimiento La Libreria Estandar de C tambien recibio numerosos cambios incorporando la mayoria de las bibliotecas definidas en el documento C Technical Report 1 TR1 con la excepcion de la biblioteca de funciones matematicas especiales El borrador mas parecido al C 11 publicado es el N3337 del 16 de enero de 2012 el cual realiza solo algunas correcciones editoriales al estandar Indice 1 Directivas de diseno 2 Extensiones al nucleo del lenguaje 3 Mejoras al rendimiento en tiempo de ejecucion 3 1 Referencias rvalue y los move constructor 3 2 Expresiones constantes generalizadas 3 3 Modificacion a la definicion de plain old data 4 Mejoras en el rendimiento del nucleo del lenguaje en tiempo de compilacion 4 1 Plantilla Extern 5 Mejoras en la usabilidad del nucleo del lenguaje 5 1 Inicializador de listas 5 2 Inicializacion uniforme 5 3 Inferencia de tipo 5 4 Bucle for basado en rango 5 5 Funciones lambda y expresiones 5 6 Sintaxis alternativa de funcion 5 7 Mejora en la construccion de objetos 5 8 Override y final explicitos 5 9 Constante de puntero null 5 10 Enumeraciones de tipo estricto 5 11 Parentesis de angulo del lado derecho 5 12 Operadores de conversion explicitos 5 13 Alias de plantillas 5 14 Uniones sin restriccion 5 15 Identificadores con significado especial 6 Mejoras en la funcionalidad del nucleo del lenguaje 6 1 Plantillas de Variadic 6 2 Nuevos literales de string 6 3 Literales definidos por el usuario 6 4 Modelo de memoria de multitarea 6 5 Almacenamiento de hilo local 6 6 Miembros de funciones especiales defaulted y deleted explicitos 6 7 Tipo long long int 6 8 Aserciones estaticas 6 9 Permite a sizeof trabajar en miembros de clases sin un objeto explicito 6 10 Permite implementaciones con recoleccion de basura 7 Cambios en la biblioteca estandar de C 7 1 Actualizaciones a los componentes de la biblioteca estandar 7 2 Facilidades de hilos 7 3 Tipos tuple 7 4 Tablas hash 7 5 Expresiones regulares 7 6 Punteros inteligentes de proposito general 7 7 Facilidad de numero random extensible 7 8 Referencia wrapper 7 9 Envoltorios polimorficos para objetos de funcion 7 10 Type traits para metaprogramacion 7 11 Metodo uniforme para computar el tipo de retorno de objetos de funcion 8 Caracteristicas eliminadas u obsoletas 9 Caracteristicas eliminadas u obsoletas 10 Lectura adicional 10 1 Documentos del Comite de Estandar de C 10 2 Articulos 11 Vease tambien 12 Notas 13 Referencias 14 Enlaces externosDirectivas de diseno EditarEn el desarrollo de cada utilidad del nuevo estandar el comite ha aplicado algunas directivas Mantener la estabilidad y la compatibilidad con C 98 y posiblemente con C Preferir la introduccion de nuevas caracteristicas a traves de la biblioteca estandar en lugar de modificar el nucleo del lenguaje Preferir los cambios que puedan hacer evolucionar las tecnicas de programacion Mejorar C para facilitar el diseno de sistemas y bibliotecas en vez de introducir nuevas caracteristicas solamente utiles a aplicaciones especificas Incrementar la seguridad de los tipos de datos suministrando alternativas mas seguras a las tecnicas inseguras anteriores Incrementar el rendimiento y la habilidad de trabajar directamente con hardware Proveer soluciones apropiadas para los problemas del mundo real Implementar el principio de zero overhead soporte adicional requerido por algunas utilidades debe ser usado solo si la utilidad es usada Hacer que C sea mas facil de ensenar y aprender sin la remocion de cualquier utilidad necesaria por los programadores expertos La atencion a los principiantes es muy importante porque ellos siempre seran la mayoria entre los programadores y porque muchos principiantes no intentarian ampliar su conocimiento de C limitandose ellos mismos a operar en los aspectos del lenguaje en el que estan especializados Adicionalmente considerando la vastedad de C y de su uso incluyendo areas de aplicacion y estilos de programacion incluso los programadores mas experimentados pueden convertirse en principiantes en un nuevo paradigma de programacion Extensiones al nucleo del lenguaje EditarUna funcion del comite de C es el desarrollo del nucleo del lenguaje Las areas del nucleo del lenguaje que fueron significativamente mejoradas incluyen el soporte multithreading multihilo el soporte de programacion generica la inicializacion uniforme y mejoras del rendimiento Para los propositos de este articulo las caracteristicas y los cambios del nucleo del lenguaje son agrupadas en 4 secciones generales Mejoras al rendimiento en tiempo de ejecucion Mejoras en el rendimiento en tiempo de compilacion Mejoras en la usabilidad Nueva funcionalidadAlgunas caracteristicas podrian entrar en multiples grupos pero solo son mencionadas en el grupo que primariamente representa esa caracteristica Mejoras al rendimiento en tiempo de ejecucion EditarEstas caracteristicas del lenguaje existen primariamente para proporcionar un cierto tipo de beneficio en el rendimiento tanto de la memoria como de la velocidad computo Referencias rvalue y los move constructor Expresiones constantes generalizadas Modificacion a la definicion de plain old dataReferencias rvalue y los move constructor Editar En el C 03 y anteriores los temporales llamados rvalues pues a menudo se encuentran en el lado derecho de una asignacion fueron pensados para nunca ser modificables justo como en C y eran considerados ser indistinguibles de los tipos const T amp aunque en algunos casos los temporales habrian podido ser modificados e incluso era considerados ser un util agujero de escape loophole para el anterior ver Sutter Alexandrescu C coding standards 15 C 11 agrega un nuevo tipo de referencia no constante llamado una referencia rvalue identificada por T amp amp Esto refiere a los temporales en que se permite que sean modificados despues de que son inicializados con el proposito de permitir la semantica del movimiento move semantics Un problema de rendimiento cronico con el C 03 son las costosas e innecesarias copias profundas que pueden suceder implicitamente cuando los objetos son pasados por valor Para ilustrar el problema considere que un std vector lt T gt es internamente una envoltura wrapper alrededor de una tabla array de estilo C con un tamano Si un std vector lt T gt temporal se crea en una funcion solamente se puede almacenar creando un nuevo std vector lt T gt y copiando todos los datos rvalue en el Luego el temporal y toda su memoria es destruido Por simplicidad este argumento deja de lado la optimizacion del valor devuelto En el C 11 un move constructor del std vector lt T gt que toma una referencia rvalue a un std vector lt T gt puede simplemente copiar el puntero a la variable interna de estilo C fuera del rvalue en el nuevo std vector lt T gt entonces cambiar el puntero dentro del rvalue a null Debido a que se puede reinicializar el puntero temporal el objeto no se borra cuando se sale del ambito scope y no es necesaria una copia profunda Por otra parte es una operacion segura e invisible porque el temporal nunca se usara otra vez Las referencias de rvalue pueden proporcionar beneficios de rendimiento al codigo existente sin la necesidad realizar cualquier cambio fuera de la biblioteca estandar El tipo del valor retornado de una funcion que retorna un std vector lt T gt temporal no necesita ser cambiado explicitamente al std vector lt T gt amp amp para invocar al move constructor pues los temporales son considerados automaticamente como rvalues Sin embargo si std vector lt T gt es la version del C 03 sin un move constructor despues el copy constructor sera invocado con un const std vector lt T gt amp como se hace normalmente incurriendo en una significativa asignacion de memoria Por razones de la seguridad algunas restricciones son impuestas Una variable nombrada nunca sera considerada para ser un rvalue incluso si se ha declarado como tal para conseguir un rvalue la plantilla de funcion std move lt T gt debe ser usada Tambien las referencias de rvalue solamente pueden ser modificadas bajo ciertas circunstancias siendo pensado para ser usado primariamente con los move constructor Debido a la naturaleza de la fraseologia de las referencias rvalue y a una cierta modificacion a la fraseologia para las referencias del lvalue referencias regulares las referencias rvalue permiten a los desarrolladores proporcionar forwarding de funciones perfectos Cuando se combina con las plantillas variadic esta capacidad permite plantillas de funcion que pueden perfectamente remitir forward argumentos a otra funcion que tome esos argumentos particulares Esto es mas util para forwarding de parametros del constructor para crear funciones de factoria que llamaran automaticamente al constructor correcto para los particulares argumentos Expresiones constantes generalizadas Editar El C siempre ha tenido el concepto de expresiones constantes Estas son expresiones tales como 3 4 que daran siempre los mismos resultados en tiempo de compilacion y en tiempo de ejecucion Las expresiones constantes son oportunidades de optimizacion para los compiladores y los compiladores frecuentemente las ejecutan en tiempo de compilacion y luego ponen los resultados codificados directamente en el programa hard coded Tambien hay un numero de lugares en donde la especificacion del C requiere el uso de expresiones constantes La definicion de un arreglo requiere una expresion constante y los valores del enumerador deben ser expresiones constantes Sin embargo las expresiones constantes siempre han terminado cuando una llamada de funcion o un constructor de objeto sea encontrado Asi que una pieza de codigo tan simple como esta es ilegal int dame cinco return 5 int algun valor dame cinco 7 Crea un arreglo de 12 enteros Ilegal en C Este no es C legal porque dame cinco 7 no es una expresion constante El compilador no tiene manera de saber si dame cinco es realmente constante en tiempo de ejecucion En teoria esta funcion podia afectar a una variable global llamar a otras funciones constantes de no tiempo de ejecucion etc C 11 introdujo la palabra clave constexpr expresion constante que permite al usuario garantizar que una funcion o un constructor de objeto es constante en tiempo de compilacion El ejemplo de arriba puede ser reescrito como sigue constexpr int dame cinco return 5 int algun valor dame cinco 7 Crea un arreglo de 12 enteros Legal en C 11 Esto permite que el compilador entienda y verifique que dame cinco es una constante en tiempo de compilacion El uso del constexpr en una funcion impone limitaciones muy estrictas en lo que esa funcion puede hacer Primero la funcion debe tener un tipo de retorno que no sea void En segundo lugar el contenido de la funcion debe ser de la forma return expresion Tercero la expresion debe ser una expresion de constante despues de la sustitucion del argumento Esta expresion constante puede solamente llamar a otras funciones definidas como constexpr o puede usar otras variables de datos de expresiones constantes Por ultimo una funcion con esta etiqueta no puede ser llamada hasta que es definida en esta unidad de traduccion translation unit Las variables tambien pueden ser definidas como valores de expresiones constantes constexpr double aceleracion de gravedad 9 8 constexpr double gravedad lunar aceleracion de gravedad 6 0 Las variables de los datos de la expresion constante son implicitmente const Solo pueden almacenar los resultados de expresiones constantes o de constructores de expresiones constantes Para construir valores de datos de expresion constante desde tipos definidos por el usurario los constructores tambien pueden ser declarados con constexpr Un constructor de expresion constante debe ser definido antes de su uso en la unidad de traduccion como con las funciones de expresion constante Debe tener un cuerpo de funcion vacio Debe inicializar a sus miembros con expresiones constantes Los destructores para tales tipos deben ser triviales Para copiar tipos construidos constexpr tambien deben ser definidos como constexpr para permitir que retornen por valor desde una funcion constexpr Cualquier funcion miembro de una clase tal como copy constructors sobrecarga de operadores etc pueden ser declaradas como constexpr siempre y cuando adapten la definicion para expresiones constantes de funcion Esto permite al compilador copiar clases en tiempo de compilacion realiza operaciones en ellas etc Una funcion de expresion constante o un constructor puede ser llamado con parametros que no sean constexpr Justo como un literal de numero entero constexpr puede ser asignado a una variable que no sea constexpr asi que una funcion constexpr tambien puede ser llamada con parametros que no sean constexpr y los resultados almacenados en variables que no sean constexpr La palabra clave solo permite la posibilidad de constante de tiempo de compilacion cuando todos los miembros de una expresion son constexpr Modificacion a la definicion de plain old data Editar En el C 03 una clase o struct debe seguir un numero de reglas para que sea considerado un tipo plain old data POD Los tipos que cumplen esta definicion producen layouts de objetos que son compatibles con C Sin embargo la definicion en C 03 es innecesariamente estricta y hay buenas razones para permitir a mas tipos cumplir la definicion de POD cita requerida C 11 relajo varias de las reglas cita requerida Una clase struct es considerada una POD si es trivial de standard layout y si todos sus miembros no estaticos son POD Una clase o struct trivial se define como uno los siguientes Tiene un constructor trivial por defecto Este puede usar la sintaxis de constructor por defecto AlgunConstructor default Tiene constructores copy y move triviales que pueden usar la sintaxis por defecto Tiene operadores de asignacion copy y move triviales los cuales pueden usar la sintaxis por defecto Tiene un destructor trivial que no debe ser virtualUna clase o struct es standard layout por definicion con tal que cumpla lo siguiente No tenga funciones virtuales No tenga clases base virtuales No tenga clases base del mismo tipo que el primer miembro de datos definido no estatico Todos sus miembros de datos no estaticos tienen el mismo control de acceso publico privado protegido Todos sus miembros de datos no estaticos incluyendo cualquiera en sus clases base estan en la misma clase en la jerarquia Las reglas antedichas tambien se aplican a todas las clases base y a todos los miembros de datos no estaticos en la jerarquiaMejoras en el rendimiento del nucleo del lenguaje en tiempo de compilacion EditarPlantilla Extern Editar En el C 03 el compilador debe instanciar una plantilla siempre que una plantilla especificada completamente es encontrada en una unidad de traduccion Si la plantilla es instanciada con el mismo tipo en muchas unidades de traduccion esta puede aumentar dramaticamente el tiempo de compilacion No hay manera de prevenir esto en C 03 asi que C 11 introdujo las declaraciones de plantilla extern analogas a las declaraciones de datos extern C 03 tiene esta sintaxis para obligar al compilador a instanciar una plantilla template class std vector lt MiClase gt C 11 ahora proporciona este sintaxis extern template class std vector lt MiClase gt la cual le dice al compilador que no instancie la plantilla en esta unidad de traduccion Mejoras en la usabilidad del nucleo del lenguaje EditarEstas caracteristicas existen para el proposito primario de hacer el lenguaje mas facil usar Estas pueden mejorar la seguridad de tipo minimizar la repeticion de codigo hacer que el codigo erroneo sea menos probable etc Inicializador de listas Inicializacion uniforme Inferencia de tipos Bucle for basado en rango Funciones y expresiones lambda Sintaxis alternativa de funcion Mejora en la construccion de objetos Override y final explicitos Constante de puntero nulo Enumeraciones fuertemente tipeadas Parentesis de angulo del lado derecho Right angle bracket Operadores de conversion explicita Alias de plantillas Uniones sin restricciones Identificadores con significado especialInicializador de listas Editar C 03 heredo la caracteristica del inicializador de lista de C Un struct o un arreglo recibe una lista de argumentos en llaves cuadradas corchetes en el orden de las definiciones de los miembros en el struct Estos inicializadores de listas son recursivos asi que pueden usarlos un arreglo de structs o un struct que contiene otros structs struct Objeto float primero int segundo Objeto escalar 0 43f 10 Un objeto con primero 0 43f y segundo 10 Objeto unArreglo 13 4f 3 43 28f 29 5 934f 17 Un arreglo con tres objetos Esto es muy util para las listas estaticas o justo para inicializar un struct con un valor particular C tambien proporciona constructores para inicializar un objeto pero a menudo no son tan convenientes como el inicializador de lista Sin embargo C 03 solo permite inicializar listas en los structs y las clases que se ajustan a la definicion Plain Old Data POD C 11 extiende la inicializacion de listas asi que pueden ser usadas para todas las clases incluyendo los contenedores estandar como el std vector C 11 ata bind el concepto a una plantilla llamada std initializer list Esto permite que los constructores y otras funciones tomen inicializadores de lista como parametros Por ejemplo class ClaseDeSecuencia public ClaseDeSecuencia std initializer list lt int gt list Esto permite que ClaseDeSecuencia sea construida de una secuencia de numeros enteros como en ClaseDeSecuencia alguna variable 1 4 5 6 Esta es una clase especial de constructor llamada constructor inicializador de lista Las clases con tal constructor son tratadas especialmente durante la inicializacion uniforme ver abajo La clase std initializer list lt gt es un tipo de biblioteca estandar C 11 de primera clase Sin embargo solo pueden ser inicialmente construidos estaticamente por el compilador de C 11 con el uso de la sintaxis La lista puede ser copiada una vez construida por lo que es solamente una copia por referencia Una lista de inicializador es constante una vez que la lista del inicializador es creada sus miembros no pueden ser cambiados ni los datos en esos miembros Debido a que el initializer list es un verdadero tipo puede ser usado en otros lugares ademas de los constructores de clase Las funciones regulares pueden tomar tipos de listas inicializadas como argumentos Por ejemplo void nombre de funcion std initializer list lt float gt list nombre de funcion 1 0f 3 45f 0 4f Los contenedores estandar tambien pueden ser inicializados de las maneras siguientes std vector lt std string gt v xyzzy plugh abracadabra std vector lt std string gt v xyzzy plugh abracadabra Inicializacion uniforme Editar El C 03 tiene un numero de problemas con los tipos de inicializacion Hay varias maneras de inicializar tipos y no todas producen los mismos resultados cuando son intercambiadas La sintaxis tradicional del constructor por ejemplo puede parecerse como una declaracion de funcion y deben tomarse medidas para asegurarse que la regla del parse mas irritante no la confundira como tales Solamente los agregados y los tipos POD pueden ser inicializados con inicializadores agregados usando SomeType var stuff C 11 proporciona una sintaxis que permite la inicializacion de tipo completamente uniforme que trabaja en cualquier objeto Se expande en la sintaxis de inicializador de lista struct EstructuraBasica int x double y struct EstructuraAlterna EstructuraAlterna int x double y x x y y private int x double y EstructuraBasica var1 5 3 2 EstructuraAlterna var2 2 4 3 La inicializacion de var1 se comporta exactamente como si fuera una inicializacion de agregado Es decir cada miembro de datos de un objeto a su vez sera inicializado por copia con el correspondiente valor de la lista de inicializacion La conversion de tipo implicita sera usada cuando se necesite Si no existe ninguna conversion o solo existe un estrechamiento de conversion el programa esta malformado La inicializacion de var2 invoca al constructor Tambien se puede hacer lo siguiente struct CadenaDeIdentificacion std string nombre int identificador CadenaDeIdentificacion lee cadena return AlgunNombre 4 Note la falta de un tipo explicito La inicializacion uniforme no reemplaza la sintaxis de constructor Todavia hay momentos en que es requerida la sintaxis de constructor Si una clase tiene un constructor TypeName initializer list lt AlgunTipo gt entonces toma prioridad sobre otras formas de construccion a condicion de que la lista del inicializador se conforme al tipo de constructor de secuencia La version C 11 del std vector tiene un constructor de lista de inicializacion para su tipo de plantilla Esto significa que el siguiente codigo std vector lt int gt el vector 4 llamara al constructor de la lista del inicializador no el constructor del std vector que toma un solo parametro de tamano y crea el vector con ese tamano Para acceder al ultimo constructor el usuario necesitara usar directamente la sintaxis de constructor estandar Inferencia de tipo Editar En el C 03 y en C el tipo de una variable debe ser explicitamente especificado para poder usarlo Sin embargo con el advenimiento de los tipos de plantilla y tecnicas de metaprogramacion de plantillas puede que expresar el tipo de algo no sea facil particularmente cuando se trata de definir bien el valor de retorno de una funcion Tambien es dificil almacenar valores intermediarios en variables y posiblemente se requerira conocer las partes internas de una biblioteca de metaprogramacion particular C 11 permite que esto sea mitigado de dos maneras Primero la definicion de una variable con una inicializacion explicita puede usar la palabra clave auto Esto crea una variable del tipo especifico del inicializador auto algun extrano tipo llamable boost bind amp alguna funcion 2 1 algun objeto auto otra variable 5 El tipo algun extrano tipo llamable es simplemente lo que la plantilla particular de la funcion override de boost bind retorna para esos argumentos particulares Este tipo es facilmente determinado por procedimiento por el compilador como parte de sus trabajos de analisis semantico pero no es facil de determinar por inspeccion por el usuario El tipo otra variable tambien esta bien definido pero es mas facil de determinar por el usuario Es un int el cual es el mismo tipo que el literal de numero entero Adicionalmente la palabra clave decltype puede ser usada para determinar el tipo de una expresion en tiempo de compilacion Por ejemplo int algun entero decltype algun entero otra variable entera 5 Esto es mas util conjuntamente con auto puesto que el tipo de una variable auto es solo conocido por el compilador Sin embargo el decltype tambien puede ser muy util para las expresiones en el codigo que hacen un fuerte uso de sobrecarga de operador y de tipos especializados auto es tambien util para reducir la verbosidad del codigo Por ejemplo en vez de escribir for std vector lt int gt const iterator iterador mi vector cbegin iterador mi vector cend iterador el programador puede utilizar el mas corto for auto iterador mi vector cbegin iterador mi vector cend iterador Esta diferencia crece a medida que el programador comienza a anidar los contenedores aunque en tales casos los typedefs son una buena manera de disminuir la cantidad de codigo El tipo denotado por el decltype puede ser diferente del tipo deducido por auto include lt vector gt int main const std vector lt int gt v 1 auto a v 0 a tiene el tipo int decltype v 0 b 1 b tiene el tipo const int amp el tipo de retorno de std vector lt int gt operator size type const auto c 0 c tiene el tipo int auto d c d tiene el tipo int decltype c e e tiene el tipo int el tipo de la entidad llamada por c decltype c f c f tiene el tipo int amp porque c es un lvalue decltype 0 g g tiene el tipo int porque 0 es un rvalue Bucle for basado en rango Editar En el C 03 la iteracion sobre los elementos de una lista requiere mucho codigo Otras lenguajes como C y Java tienen atajos que permitan escribir una simple declaracion foreach que camina automaticamente por la lista desde el comienzo hasta el final C 11 agrego una caracteristica similar La declaracion for permite una iteracion facil sobre una lista de elementos int mi arreglo 5 1 2 3 4 5 for int amp x mi arreglo x 2 Esta forma de for llamada for basado en rango iterara sobre cada elemento en la lista Trabajara para los arreglos de estilo C inicializadores de listas y cualquier tipo que tenga definida una funcion begin y end que retorne iteradores Todos los contenedores de biblioteca estandar que tienen pares begin end trabajaran con la sentencia for basada en rango Funciones lambda y expresiones Editar Articulo principal Funcion anonima C C 11 proporciona la capacidad de crear funciones anonimas llamadas funciones lambda Estas se definen como sigue int x int y return x y El tipo de retorno esta implicito devuelve el tipo de la expresion de retorno decltype x y El tipo de retorno de una lambda puede ser omitido siempre y cuando todas las expresiones de retorno devuelven el mismo tipo Sintaxis alternativa de funcion Editar la sintaxis de declaracion de una funcion estandar de C era perfectamente adecuada para el conjunto de caracteristicas de este lenguaje A medida que C evoluciono desde el C mantuvo la sintaxis basica extendiendola en caso necesario Sin embargo a medida que C llego a ser mas complicado expuso un numero de limitaciones particularmente con respecto a declaraciones de funciones de plantilla Lo siguiente por ejemplo no es permitido en C 03 template lt class Lhs class Rhs gt Ret funcion de suma const Lhs amp lhs const Rhs amp rhs return lhs rhs Ret debe ser el tipo de lhs rhs El tipo Ret es cualquier cosa que la adicion de los tipos Lhs y Rhs produzca Incluso con la ya mencionada funcionalidad C 11 del decltype esto no es posible template lt class Lhs class Rhs gt decltype lhs rhs funcion de suma const Lhs amp lhs const Rhs amp rhs return lhs rhs No es legal en C 11 Esto no es C legal porque lhs y rhs todavia no se han definido no seran identificadores validos hasta despues de que el parser haya analizado el resto del prototipo de la funcion Para solucionarlo C 11 introdujo una nueva sintaxis de declaracion de funcion con el tipo de retorno al final template lt class Lhs class Rhs gt auto funcion de suma const Lhs amp lhs const Rhs amp rhs gt decltype lhs rhs return lhs rhs Esta sintaxis puede ser usada para declaraciones y definiciones de funciones mas mundanas struct AlgunaEstructura auto nombre de funcion int x int y gt int auto AlgunaEstructura nombre de funcion int x int y gt int return x y En este caso el uso de la palabra clave auto significa algo diferente de su uso en la deduccion de tipo automatica Mejora en la construccion de objetos Editar En C 03 a los constructores de una clase no se les permite llamar a otros constructores de esa clase cada constructor debe construir todos sus miembros de clase por si mismo o llamar a una funcion de miembro comun como los siguientes class AlgunTipo int numero public AlgunTipo int nuevo numero numero nuevo numero AlgunTipo numero 42 class AlgunTipo int numero private void Construct int nuevo number numero nuevo numero public AlgunTipo int nuevo numero Construct nuevo numero AlgunTipo Construct 42 Los constructores para las clases base no pueden ser expuestos directamente a las clases derivadas cada clase derivada debe implementar constructores incluso si un constructor de clase base fuera apropiado los miembros de datos no constantes de las clases no pueden ser inicializados en el sitio de la declaracion de esos miembros Solo pueden ser inicializados en un constructor El C 11 proporciona soluciones a todos estos problemas El C 11 permite a los constructores llamar a otros constructores pares conocidos como delegacion Esto permite a los constructores usar el comportamiento de otro constructor con un minimo de codigo anadido Ejemplos de otros lenguajes similares a C que proporcionen la delegacion son Java C y D Esta sintaxis es como sigue class AlgunTipo int numero public AlgunTipo int nuevo numero numero nuevo numero AlgunTipo AlgunTipo 42 Note que en este caso el mismo efecto habria podido ser alcanzado haciendo new number un parametro por defecto Sin embargo la nueva sintaxis permite que al valor por defecto 42 sea expresado en la implementacion en vez de la interfaz un beneficio para los mantenedores del codigo de la biblioteca puesto que los valores por defecto para los parametros de la funcion son horneados para llamar sitios mientras que la delegacion del constructor permite que el valor sea cambiado usando la biblioteca sin la recompilacion del codigo Esto viene con una advertencia C 03 considera un objeto a ser construido cuando su constructor termine de ejecutarse pero C 11 considera un objeto construido una vez que cualquier constructor termine su ejecucion Puesto que se permitira ejecutar a multiples constructores esto significara que cada constructor delegado ejecutara en un objeto completamente construido de su propio tipo Los constructores de clase derivados ejecutaran despues de que toda la delegacion en sus clases base este completa Para los constructores de la clase base el C 11 permite a una clase especificar que los constructores de la clase base sean heredados Esto significa que el compilador C 11 generara codigo para realizar la herencia el forwarding de clase derivada a la clase base Observe que esto es una caracteristica de todo o nada todos los constructores de esa clase base son forwarded o ningunos de ellos lo son Tambien observe que hay restricciones para la herencia multiple de tal manera que los constructores de clase no pueden ser heredados a partir de dos clases que usen constructores con la misma firma Ni puede existir un constructor en la clase derivada que tenga una firma igual en la clase base heredada la sintaxis es como sigue class ClaseBase public ClaseBase int valor class ClaseDerivada public ClaseBase public using ClaseBase ClaseBase Para la inicializacion de miembros C 11 permite la siguiente sintaxis class AlgunaClase public AlgunaClase explicit AlgunaClase int nuevo valor valor nuevo valor private int valor 5 Cualquier constructor de la clase inicializara el valor en 5 si el constructor no sobreescribe la inicializacion con las propios Asi que el constructor vacio de arriba inicializara el valor como establece la definicion de la clase pero el constructor que toma un int lo inicializara con el parametro dado Tambien puede usar la inicializacion de constructor o uniforme en vez de la inicializacion de igualdad mostrada arriba Override y final explicitos Editar En C 03 es posible crear accidentalmente una nueva funcion virtual cuando en realidad uno solo se prepuso un override de una funcion de la clase base Por ejemplo struct Base virtual void alguna funcion float struct Derivada Base virtual void alguna funcion int Por ejemplo queremos disenar Derivada alguna funcion para reemplazar la version de la clase base Pero debido a que la funcion virtual tiene una firma diferente en realidad crea una segunda funcion virtual Esto es un problema comun particularmente cuando un usuario va a modificar la clase base C 11 proporciona una sintaxis para solucionar este problema struct Base virtual void alguna funcion float struct Derivada Base virtual void alguna funcion int override Mal formado porque no hace un override de un metodo de la clase base El identificador especial override significa que el compilador comprobara la clase base para ver si hay una funcion virtual con esta firma exacta Y si no la hay el compilador producira un error C 11 tambien agrega la capacidad de prevenir poder heredar clases o sobrecargar funciones especificas Esto se consigue con el identificador especial final Por ejemplo struct Base1 final struct Derivada1 Base1 Mal formado porque la clase base esta marcada como final struct Base2 virtual void f final struct Derivada2 Base2 void f Mal formado porque la funcion virtual Base2 f esta marcada como final En este ejemplo la sentencia virtual void f final declara una nueva funcion virtual pero tambien previene a las clases derivadas poder sobrecargarla Tambien tiene el efecto de prevenir a las clases derivadas de usar esa combinacion particular de nombre de funcion y parametros Observe que ni override ni final son palabras claves del lenguaje Tecnicamente son identificadores solo ganan un significado especial cuando son usados en esos contextos especificos En cualquier otra localizacion pueden ser identificadores validos Constante de puntero null Editar Unicamente para los propositos de esta seccion cada ocurrencia de 0 significara expresion constante que se evalua a 0 que es del tipo entero int En realidad la expresion constante puede ser de cualquier tipo entero Desde el amanecer de C en 1972 la constante 0 ha tenido el doble papel de constante de numero entero y de constante de puntero nulo La ambiguedad inherente en el doble significado de 0 fue tratada en C por el uso del macro NULL del preprocesador que comunmente expande a void 0 o 0 C no adopto el mismo comportamiento permitiendo a 0 solamente como constante del puntero nulo Esto interactua mal con la sobrecarga de funciones void foo char void foo int Si NULL esta definido como 0 lo usual en el caso del C la sentencia foo NULL llamara a foo int que casi con toda certeza no es lo que penso el programador y no es lo que sugiere una lectura superficial del codigo C 11 corrige esto introduciendo una nueva palabra clave para servir como constante inconfundible de puntero nulo nullptr Es del tipo nullptr t que es implicitamente convertible y comparable a cualquier tipo de puntero o tipo de puntero a miembro No es implicitamente convertible o comparable a los tipos enteros a excepcion de bool Mientras que la propuesta original especifico que un rvalue del tipo nullptr no deberia ser convertible a bool el grupo de trabajo del nucleo del lenguaje decidio que tal conversion seria deseable para la consistencia con los tipos punteros regulares Los cambios de redaccion propuestos fueron votados unanimemente en el documento de trabajo en junio de 2008 1 Por razones de compatibilidad hacia atras 0 sigue siendo un constante de puntero nulo valida char pc nullptr OK int pi nullptr OK bool b nullptr OK b es false int i nullptr error foo nullptr invoca foo char no foo int Enumeraciones de tipo estricto Editar En C 03 las enumeraciones no son de tipo seguro Internamente en realidad son numeros enteros incluso cuando los tipos de la enumeracion son distintos Esto permite la comparacion entre dos valores de diferentes tipos de enumeracion La unica seguridad que C 03 proporciona es que un numero entero o un valor de un tipo enum no se convierte implicitamente a otro tipo enum Ademas el tipo int subyacente esta definido por la implementacion del compilador Por lo tanto el codigo que depende del tamano de la enumeracion no es portable Por ultimo los valores de la enumeracion tienen un ambito definido por el ambito que los encierra Asi no es posible que dos enumeraciones separadas tengan nombres de miembro que emparejen C 11 permitira una clasificacion especial de la enumeracion que no tiene ninguno de esos problemas Esto es expresado usando la declaracion enum class enum struct tambien es aceptado como un sinonimo enum class Enumeracion Valor1 Valor2 Valor3 100 Valor4 101 Esta enumeracion es de tipo seguro los valores de enum class no son convertidos implicitamente a numeros enteros Por lo tanto no pueden ser comparados con numeros enteros la expresion Enumeracion Valor4 101 da un error del compilador El tipo subyacente de los miembros de las clases de enum no estara predefinido Por defecto como en el caso anterior es int pero puede ser especificado explicitamente a un tipo diferente enum class Enumeracion2 unsigned int Valor1 Valor2 El ambito de la enumeracion tambien esta definido como el ambito del nombre de la enumeracion Usando los nombres de enumerador requiere explicitamente el uso de ambitos Valor1 es indefinido pero Enumeracion2 Valor1 esta definido Adicionalmente C 11 permitira que las enumeraciones estandar proporcionen un ambito explicito asi como la definicion del tipo subyacente enum Enumeracion3 unsigned long Valor1 1 Valor2 Los nombres del enumerador son definidos en el ambito de la enumeracion Enumeracion3 Valor1 pero para la compatibilidad hacia atras los nombres del enumerador tambien son colocados en el ambito de encerrado La declaracion de enums tambien es posible en C 11 Previamente los tipos de enum no podian ser declarados porque el tamano de la enumeracion depende de la definicion de sus miembros Siempre que el tamano de la enumeracion sea especificado implicita o explicitamente puede ser declarado lo siguiente enum Enumeracion1 Ilegal en C y C 11 el tipo subyacente no puede ser determinado enum Enumeracion2 unsigned int Legal en C 11 el tipo subyacente esta especificado explicitamente enum class Enumeracion3 Legal en C 11 el tipo subyacente es int enum class Enumeracion4 unsigned int Legal en C 11 enum Enumeracion2 unsigned short Ilegal en C 11 porque Enumeracion2 estaba declarado con un tipo subyacente diferente Parentesis de angulo del lado derecho Editar El parser del C 03 define gt gt como el operador de desplazamiento derecho en todos los casos Sin embargo con declaraciones jerarquizadas de plantilla hay una tendencia para que el programador descuide poner un espacio entre los dos parentesis de angulo derecho causando por lo tanto un error de sintaxis del compilador C 11 mejorara la especificacion del parser de modo que multiples parentesis de angulo derechos sean interpretados donde sea razonable como cierre de la lista de argumentos de la plantilla Esto puede ser sobreescrito usando parentesis template lt bool Prueba gt class AlgunTipo std vector lt AlgunTipo lt 1 gt 2 gt gt x1 Interpretado como un std vector de AlgunTipo lt true gt 2 gt lo cual NO es una sintaxis legal 1 es true std vector lt AlgunTipo lt 1 gt 2 gt gt x1 Interpretado como un std vector de AlgunTipo lt false gt Lo cual SI es una sintaxis legal en C 11 1 gt 2 es false Operadores de conversion explicitos Editar C 03 agrego la palabra clave explicit como un modificador para prevenir que los constructores con un solo argumento fueran usados como operadores de conversion de tipo implicito Sin embargo esto no hace nada por los reales operadores de conversion Por ejemplo una clase puntero inteligente puede tener un operator bool para permitir que actue mas como un puntero primitivo si incluye esta conversion puede ser probada con if smart ptr variable el cual seria true si el puntero no fuera null y de lo contrario false Sin embargo esto tambien permite otras conversiones no intencionales Puesto que el bool de C es definido como tipo aritmetico puede ser implicitamente convertido a los tipos entero o aun a los tipos flotantes lo que permite las operaciones matematicas que no fueron pensadas por el usuario En C 11 la palabra clave explicit ahora puede ser aplicada a los operadores de conversion Como con los constructores previene el uso de funciones de conversion en conversiones implicitas Sin embargo contextos del lenguaje que especificamente requieren valor boleano las condiciones de sentencias if y en bucles tan bien como operandos en operadores logicos como en conversiones explicitas y por lo tanto pueden usar a un operador de conversion bool Alias de plantillas Editar En C 03 solo es posible definir un typedef como un sinonimo para otro tipo incluyendo un sinonimo para una especializacion de plantilla con todos los argumentos reales de la plantilla especificados No es posible crear una plantilla de typedef como la siguiente template lt typename Primero typename Segundo int tercero gt class AlgunTipo template lt typename Segundo gt typedef AlgunTipo lt OtroTipo Segundo 5 gt TypedefName Ilegal en C Esto no compilara C 11 agregara esta capacidad con la siguiente sintaxis template lt typename Primero typename Segundo int tercero gt class AlgunTipo template lt typename Segundo gt using TypedefName AlgunTipo lt OtroTipo Segundo 5 gt En C 11 la sintaxis tambien puede ser usada para alias de tipos typedef void Tipo double Viejo estilo using Tipo void double Nueva sintaxis introducida Uniones sin restriccion Editar En C 03 hay restricciones en que tipos de objetos pueden ser miembros de una union Por ejemplo las uniones no pueden contener objetos que definan a un constructor no trivial C 11 suprime algunas de estas restricciones 2 Este es un simple ejemplo de una union permitida en C for placement new include lt new gt struct Punto Punto Punto int x int y x x y y int x y union U int z double w Punto p Ilegal en C Punto tiene un constructor no trivial Sin embargo esto es legal en C 11 U new amp p Punto Funciones miembro no triviales son definidas implicitamente por una union Si se requiere en su lugar ellas son borradas para forzar una definicion manual Los cambios no romperan ningun codigo existente puesto que solamente se relajan las reglas actuales Identificadores con significado especial Editar Los identificadores override y final tienen un significado especial solo cuando son usados en un cierto contexto de lo contrario pueden usarse como identificadores normales Mejoras en la funcionalidad del nucleo del lenguaje EditarEstas caracteristicas permiten al lenguaje hacer cosas que eran previamente imposibles excesivamente verbosas o requerian bibliotecas no portables Plantillas variadic Nuevos literales de string Literales definidos por el usuario Modelo de memoria multitarea Almacenamiento local de hilos Miembros de funciones especiales defaulted y deleted explicitos Tipo long long int Aserciones estaticas Permitir a sizeof trabajar en miembros de clase sin un objeto explicito Permitir implementaciones de recoleccion de basuraPlantillas de Variadic Editar Articulo principal Plantillas variadic En C 11 las plantillas pueden tomar numeros variables de parametros Esto tambien permite la definicion de funciones variadic tipo seguro Nuevos literales de string Editar C 03 ofrece dos clases de literales de string cadena La primera clase contenida dentro de comillas dobles produce un arreglo terminado en null de tipo const char La segunda clase definida como L produce un arreglo terminado en null de tipo const wchar t donde wchar t es un caracter ancho Ninguno de los tipos literales ofrece soporte para literales de string con UTF 8 UTF 16 o cualquier otra clase de codificaciones de Unicode Con el proposito de realzar en los compiladores de C el soporte de unicode la definicion del tipo char ha sido modificada para que tenga por lo menos el tamano necesario para almacenar una codificacion UTF 8 de ocho bits y lo suficientemente grande como para contener cualquier miembro del juego de caracteres de ejecucion basicos del compilador Anteriormente estaba definida solo como esto ultimo Ademas de este cambio en la definicion de char C 11 soportara tres codificaciones de Unicode UTF 8 UTF 16 y UTF 32 y anadira dos nuevos tipos de caracter char16 t y char32 t Estos estan disenados para almacenar UTF 16 y UTF 32 respectivamente El ejemplo siguiente muestra como crear literales string para cada una de estas codificaciones u8 I m a UTF 8 string u This is a UTF 16 string U This is a UTF 32 string El tipo del primer string es el habitual const char El tipo del segundo string es const char16 t y el tipo del tercero es const char32 t Al construir literales de string unicode a menudo es util insertar codigos de unicode directamente Para ello C 11 permitira la siguiente sintaxis u8 This is a Unicode Character u2018 u This is a bigger Unicode Character u2018 U This is a Unicode Character u2018 El numero despues del u es un numero hexadecimal sin necesidad del prefijo 0x El identificador u representa un codigo de unicode de 16 bits para insertar un codigo de 32 bits se usa U y un numero hexadecimal de 32 bits Solamente se admiten codigos validos de Unicode Por ejemplo los valores en el intervalo U D800 U DFFF estan prohibidos pues estan reservados para los pares sustitutos en las codificaciones UTF 16 A veces tambien es util evitar secuencias de escape de string manuales particularmente al usar literales de archivos XML lenguajes de scripting o de expresiones regulares C 11 proporcionara un literal de cadena raw R The String Data Stuff R delimiter The String Data Stuff delimiter En el primer caso todo entre y es parte del string Los caracteres y no necesitan secuencia de escape En el segundo caso el delimiter inicia la cadena y solamente se termina al encontrar delimiter El delimiter puede ser cualquier literal de hasta 16 caracteres de longitud Este no puede contener espacios caracteres de control o los caracteres o El uso de este delimitador permite que el usuario tenga caracteres dentro de literales de cadena raw Por ejemplo R delimiter a z delimiter es equivalente a a z 3 Los literales de cadena raw pueden combinarse con los prefijos de literal ancho o con cualquiera de los prefijos de literal unicode u8R XXX I m a raw UTF 8 string XXX uR This is a raw UTF 16 string UR This is a raw UTF 32 string Literales definidos por el usuario Editar C 03 proporciona un numero de literales Los caracteres 12 5 son un literal que es resuelto por el compilador como tipo double con el valor de 12 5 Sin embargo la adicion del sufijo f como en 12 5f crea un valor del tipo float que contiene el valor 12 5 Los modificadores de sufijo para los literales son fijados por la especificacion del C y el codigo de C no puede crear nuevos modificadores literales C 11 tambien incluira la capacidad para que el usuario defina nuevas clases de modificantes literales que construyan objetos basados en string de caracteres que el literal modifique La transformacion de los literales es redefinida en dos fases distintas raw y cooked crudo y cocinado Un literal raw es una secuencia de caracteres de un cierto tipo especifico mientras que el literal cocinado es de un tipo separado El literal 1234 de C como literal crudo es esta secuencia de caracteres 1 2 3 4 Como literal cocinado es el numero entero 1234 El literal 0xA de C en forma cruda es 0 x A mientras que en forma cocinada es el numero entero 10 Los literales pueden ser extendidos tanto en formas crudas y cocinadas con la excepcion de los literales de string que solo se pueden procesar en forma cocinada Esta excepcion es debido al hecho de que los string tienen prefijos que afecten al significado y al tipo especificos de los caracteres en cuestion Todos los literales definidos por el usuario son sufijos la definicion de literales de prefijo no es posible Los literales definidos por el usuario que procesan la forma cruda del literal son definidos como sigue OutputType operator suffix const char literal string OutputType some variable 1234 suffix La segunda declaracion ejecuta el codigo definido por la funcion literal definida por el usuario A esta funcion se le pasa 1234 como un string de estilo C asi que tiene un terminador null Un mecanismo alternativo para procesar literales de numero entero y punto flotante crudos es a traves de una plantilla variadic template lt char gt OutputType operator suffix OutputType some variable 1234 suffix OutputType another variable 2 17 suffix Esto instancia la funcion de procesamiento literal como operator suffix lt 1 2 3 4 gt En esta forma no hay caracter null terminal en el string El proposito principal para hacer esto es utilizar palabra clave constexpr de C 11 y permitir al compilador que el literal sea transformado enteramente en tiempo de compilacion asumiendo que OutputType es un tipo constexpr construible y copiable y la funcion de procesamiento literal es una funcion constexpr Para los literales numericos el tipo de literal cocinado es unsigned long long para literales enteros o long double para los literales de punto flotante Nota No hay necesidad de tipos entero con signo porque un literal con prefijo de signo es parseado como expresion que contiene el signo como operador de prefijo unario seguido del numero sin signo No hay forma de plantilla alternativa OutputType operator suffix unsigned long long OutputType operator suffix long double OutputType some variable 1234 suffix usa la primera funcion OutputType another variable 3 1416 suffix usa la segunda funcion Para los literales de string de acuerdo con los prefijos de string previamente mencionados son usados OutputType operator suffix const char string values size t num chars OutputType operator suffix const wchar t string values size t num chars OutputType operator suffix const char16 t string values size t num chars OutputType operator suffix const char32 t string values size t num chars OutputType some variable 1234 suffix Llama la version de la const char OutputType some variable u8 1234 suffix Llama la version de la const char OutputType some variable L 1234 suffix Llama la version de la const wchar t OutputType some variable u 1234 suffix Llama la version de la const char16 t OutputType some variable U 1234 suffix Llama la version de la const char32 t No hay forma alternativa de plantilla Los literales de caracter son definidos similarmente Modelo de memoria de multitarea Editar Articulo principal Modelo de memoria computacion El comite estandar de C planea estandardizar el soporte para la programacion multihilo Hay dos partes implicadas La primera parte es la definicion de un modelo de memoria que permitira que multiples hilos coexistan en un programa y la definicion del soporte para la interaccion entre los hilos La segunda parte sera proporcionada via facilidades de la biblioteca Ver la seccion de este articulo C 11 Facilidades de hilos El modelo de memoria define cuando los multiples hilos pueden tener acceso a la misma posicion de memoria y especifica cuando las actualizaciones por un hilo llegan a ser visibles a otros hilos Almacenamiento de hilo local Editar En un ambiente con multi hilo es comun que cada hilo tenga algunas variables unicas Esto actualmente sucede para las variables locales de una funcion pero no sucede para las variables globales y estaticas Para el estandar ha sido propuesto una nueva duracion de almacenamiento de hilo local thread local ademas de las existentes estatico dinamico y automatico static dynamic automatic El almacenamiento de hilo local sera indicado por el especificador de almacenamiento thread local Cualquier objeto que pudiera tener la duracion de almacenamiento estatico es decir perdurar durante toda la ejecucion del programa se le puede dar la duracion de hilo local Lo que se quiere es que como cualquier otra variable de duracion estatica un objeto hilo local pueda ser inicializado usando un constructor y destruido usando un destructor Miembros de funciones especiales defaulted y deleted explicitos Editar En C 03 el compilador proporciona para las clases que no lo proporcionan por si mismas un constructor por defecto default un constructor de copia un operador de asignacion de copia operator y un destructor El programador puede sobreescribir estos comportamientos por defecto definiendo versiones personalizadas C tambien define a varios operadores globales tales como operator y operator new que trabajan sobre todas las clases y que el programador puede sobreescribir Sin embargo hay poco control sobre la creacion de estos comportamientos por defecto Hacer una clase intrinsecamente no copiable por ejemplo requiere la declaracion de un constructor de copia y de un operador de asignacion privados y la no definicion de ellos El intentar usar estas funciones es una violacion de la regla de una sola definicion Como no se requiere un mensaje de diagnostico 4 esto da lugar tipicamente a un error del enlazador linker cita requerida En el caso del constructor default el compilador no generara un constructor por defecto si una clase es definida con cualquier constructor Esto es util en muchos casos pero es tambien util para poder tener constructores especializados y el de defecto generado por el compilador C 11 permitira el default y delete explicito de estas funciones miembro especiales Por ejemplo el tipo siguiente declara explicitamente que esta usando al constructor default struct SomeType SomeType default Declara explicitamente el constructor por defecto SomeType OtherType value Alternativamente ciertas caracteristicas pueden ser inhabilitadas explicitamente Por ejemplo el tipo siguiente es no copiable struct NonCopyable NonCopyable amp operator const NonCopyable amp delete NonCopyable const NonCopyable amp delete NonCopyable default El especificador delete puede ser usado para prohibir llamar cualquier funcion lo cual puede ser usado para rechazar la llamada de una funcion de miembro con parametros particulares Por ejemplo struct NoInt void f double i void f int delete Un intento de llamar a f con un int sera rechazado por el compilador en vez de realizar una conversion silenciosa a double Esto puede ser generalizado para rechazar la llamada de la funcion con cualquier tipo con excepcion de doble de la siguiente manera struct OnlyDouble void f double d template lt class T gt void f T delete Tipo long long int Editar En C 03 el mas grande tipo entero es long int Esta garantizado que tenga por lo menos tantos bits usables como int Esto resultaba en que long int tuviera un tamano de 64 bits en algunas implementaciones populares y 32 bits en otras Para abordar este problema C 11 agrega un nuevo tipo entero long long int Esta garantizado que sea por lo menos tan grande como un long int y que tenga no menos de 64 bits El tipo fue originalmente introducido al C estandar con C99 y la mayoria de los compiladores de C ya lo soportan como extension 5 6 Aserciones estaticas Editar C 03 proporciona dos metodos para probar aserciones el macro assert y la directiva de preprocesador error Sin embargo ninguno es apropiado para el uso en plantillas el macro prueba la asercion en tiempo de ejecucion mientras que la directiva del preprocesador prueba la asercion durante el preprocesamiento que sucede antes de la instanciacion de las plantillas Ninguno es apropiado para probar las propiedades que son dependientes de parametros de plantillas La nueva utilidad introduce una nueva manera de probar aserciones en tiempo de compilacion usando la nueva palabra clave static assert La declaracion asume la siguiente forma static assert constant expression error message Aqui estan algunos ejemplos de como puede ser usado el static assert static assert GREEKPI gt 3 14 amp amp GREEKPI lt 3 15 GREEKPI is inaccurate template lt class T gt struct Check static assert sizeof int lt sizeof T T is not big enough Cuando la expresion constante es false el compilador produce un mensaje de error El primer ejemplo representa una alternativa a la directiva de preprocesador error en contraste en el segundo ejemplo la asercion es chequeada en cada instanciacion de la clase de plantilla Check Las aserciones estaticas tambien son utiles fuera de las plantillas Por ejemplo una implementacion de un algoritmo pudiera depender de que el tamano de un long long fuera mas grande que un int algo que el estandar no garantiza Tal asuncion es valida en la mayoria de los sistemas y de los compiladores pero no todos Permite a sizeof trabajar en miembros de clases sin un objeto explicito Editar En C 03 el operador sizeof puede ser usado en tipos y objetos Pero no puede ser usado para hacer lo siguiente struct SomeType OtherType member sizeof SomeType member No trabaja en C 03 Valido con C 11 Esto permite en C 11 retornar el tamano de OtherType C 03 no permite esto asi que es un error de compilacion Permite implementaciones con recoleccion de basura Editar La implementacion define si los objetos dinamicamente asignados que se vuelvan inalcanzables son reclamados automaticamente Cambios en la biblioteca estandar de C EditarUn numero de nuevas caracteristicas seran introducidas en la biblioteca estandar del C 11 Muchos de estas caracteristicas pueden ser implementadas bajo el estandar actual pero algunas dependen en mayor o menor medida en nuevas caracteristicas del nucleo de C 11 Una gran parte de las nuevas bibliotecas son definidas en el C Technical Report 1 Reporte Tecnico 1 de C llamado TR1 publicado en 2005 Estan disponibles actualmente varias implementaciones completas y parciales del TR1 usando el namespace std tr1 Para C 11 seran movidas al namespace std Sin embargo a medida que las caracteristicas del TR1 son llevadas a la biblioteca estandar de C 11 cuando sea apropiado estas son actualizadas con caracteristicas del lenguaje de C que no estaban disponibles en la version inicial del TR1 Tambien pueden ser mejoradas con las caracteristicas que eran posibles debajo el C 03 pero no eran parte de la especificacion original del TR1 El comite se prepone crear un segundo reporte tecnico llamado TR2 despues de que este completa la estandardizacion de C 11 Las propuestas de biblioteca que no esten listas para C 11 seran puestas en el TR2 u otros reportes tecnicos Las siguientes propuestas estan en curso para el C 11 Actualizaciones a los componentes de la biblioteca estandar Facilidades de hilos Tipos tuple Tablas hash Expresiones regulares Apuntadores inteligentes de proposito general Facilidad de numero aleatorio extensible Referencia de envoltorio wrapper Envoltorios polimorficos para objetos de funciones Caracteristicas de tipo para metaprogramacion Metodo uniforme para computar el tipo de retorno de objetos de funcionesActualizaciones a los componentes de la biblioteca estandar Editar C 11 ofrece un numero de nuevas caracteristicas de lenguaje de las cuales se pueden beneficiar los actuales componentes de la biblioteca estandar Por ejemplo la mayoria de los containers contenedores de la biblioteca estandar pueden beneficiarse en la referencia Rvalue basada en el soporte del move constructor tanto para mover rapidamente contenedores pesados alrededor como para mover el contenido de esos contenedores a nuevas localizaciones de memoria Los componentes de la biblioteca estandar seran actualizados con las nuevas caracteristicas de lenguaje C 11 cuando sea apropiado Estas incluyen pero no se limitan necesariamente a Referencias Rvalue y el asociado soporte para move Soporte para los tipos de caracteres Unicode de las unidades de codificacion UTF 16 y UTF 32 Plantillas variadic acopladas con las referencias de Rvalue para permitir forwarding perfecto Expresiones constantes en tiempo de compilacion Decltype Operadores de conversion explicitos Funciones Default DeletedAdicionalmente ha pasado mucho tiempo desde que C fue estandardizado Se ha escrito una gran cantidad de codigo usando la biblioteca estandar esto ha revelado porciones de las bibliotecas estandar que podrian usar alguna mejora Entre las muchas areas de mejoras que son consideradas son los allocators de la biblioteca estandar Un nuevo modelo basado en ambito scope de allocators sera incluido en el C 11 para complementar el modelo actual Facilidades de hilos Editar Mientras que el lenguaje C 11 proporcionara un modelo de memoria que soporta hilos threading el soporte primario para usar realmente hilos vendra con la biblioteca estandar del C 11 Sera proporcionada una clase de tipo hilo std thread Para correr el nuevo hilo esta clase tomara un objeto funcion y opcionalmente una serie de argumentos Sera posible hacer que un hilo se detenga hasta que otro hilo en ejecucion termine proporcionando soporte de thread joining a traves de la funcion de miembro std thread join De ser posible tambien sera proporcionado el acceso a los objetos nativos de hilo subyacentes para las operaciones especificas de la plataforma por medio de la funcion de miembro std thread native handle Para la sincronizacion entre los hilos seran agregadas a la biblioteca mutexes apropiados std mutex std recursive mutex etc y variables de condicion std condition variable y std condition variable any Esto sera accesible con locks RAII std lock guard y std unique lock y algoritmos de bloqueo locking para facil uso Para el trabajo de bajo nivel de alto rendimiento a veces es necesario la comunicacion entre los hilos sin el overhead de los mutexes Esto es alcanzado usando operaciones atomicas en localizaciones de memoria Estas pueden opcionalmente especificar las restricciones de visibilidad de memoria minimas requeridas para una operacion Las barreras de memoria explicitas tambien pueden ser usadas para este proposito La biblioteca de hilo del C 11 tambien incluira futuros y promesas para pasar resultados asincronicos entre los hilos y el std packaged task para envolver wrapping una llamada de funcion que puede generar tal resultado asincronico La propuesta de futuros fue criticada porque carece de una manera de combinar futuros y comprobar la terminacion de un interior de una promesa dentro de un conjunto de promesas 7 Otras facilidades de hilo de alto nivel tales como thread pools han sido remitidas a un futuro informe tecnico del C No seran una parte de C 11 pero su eventual implementacion es esperada a ser construida enteramente en el tope de las caracteristicas de la biblioteca de hilos La nueva facilidad std async facility proporciona un metodo conveniente de correr tareas y de atarlas a un std future El usuario puede elegir si la tarea debe correr asincronicamente en un hilo separado o sincronicamente en un hilo que espere por el valor Por defecto la implementacion puede elegir lo que proporciona una manera facil de tomar ventaja de la concurrencia del hardware sin la sobresubscripcion oversubscription y proporciona algunas de las ventajas de un thread pool para los usos simples Tipos tuple Editar Los tuples son colecciones compuestas por los objetos heterogeneos de dimensiones pre arregladas Un tuple puede ser considerado una generalizacion de un miembro de estructura de las variables La version C 11 del tuple del TR1 se beneficiara de las caracteristicas C 11 como plantillas variadic La version TR1 requeria un maximo numero de tipos de contenedor definido por la implementacion y requeria una sustancial cantidad de trucos de macro para implementarse razonablemente Por contraste la implementacion de la version C 11 no requiere ningun numero maximo de tipos definidos explicitamente por la implementacion Aunque los compiladores casi ciertamente tendran una profundidad interna maxima de recursion para la instanciacion de plantillas lo cual es normal la version de tuples de C 11 no expondra este valor al usuario Usando plantillas variadic la declaracion de clase tuple se ve como sigue template lt class Types gt class tuple Un ejemplo de la definicion y uso del tipo tuple typedef std tuple lt int double long amp const char gt test tuple long lengthy 12 test tuple proof 18 6 5 lengthy Ciao lengthy std get lt 0 gt proof Asigna a lengthy el valor 18 std get lt 3 gt proof Beautiful Modifica el cuarto elemento del tuple Es posible crear el tuple proof sin la definicion de su contenido pero solamente si los tipos de elementos del tuple poseen constructores por defecto Por otra parte es posible asignar un tuple a otro tuple si los tipos de los dos tuples son iguales es necesario que cada tipo de elemento posea un constructor copy de lo contrario es necesario que cada tipo de elemento del tuple del lado derecho sea convertible al elemento correspondiente del tuple del lado izquierdo o que el tipo de elemento correspondiente del tuple del lado izquierdo tenga un constructor conveniente typedef std tuple lt int double string gt tuple 1 t1 typedef std tuple lt char short const char gt tuple 2 t2 X 2 Hola t1 t2 Ok los primeros dos elementos pueden ser convertidos El tercer elemento puede ser construido desde un const char Hay disponibles Los operadores relacionales entre tuples con el mismo numero de elementos y hay disponibles dos expresiones para comprobar las caracteristicas de un tuple solamente durante la compilacion std tuple size lt T gt value retorna el numero de elementos de el tuple T std tuple element lt I T gt type retorna el tipo del numero de objeto I del tupleTablas hash Editar Una de las peticiones que mas se repiten es la inclusion en la biblioteca estandar de C de las tablas hash contenedores asociativos sin orden No fue adoptada en el estandar actual solo debido a restricciones de tiempo Aunque esta solucion es menos eficiente que un arbol balanceado en el peor caso en presencia de muchas colisiones en muchas aplicaciones verdaderas se desempena mejor Las colisiones seran manejadas solo a traves de encadenamiento lineal porque el comite no considera oportuno estandardizar soluciones de direccionamiento abierto que introducen bastantes de problemas intrinsecos sobre todo cuando es admitido el borrado de elementos Para evitar los choques de nombres con las bibliotecas no estandar que desarrollaran sus propias implementaciones de la tabla hash sera utilizado el prefijo unordered en vez del hash La nueva utilidad tendra cuatro tipos de tablas hash diferenciados en si aceptan o no elementos con la misma clave claves unicas o claves equivalentes y si mapean cada clave a un valor asociado Tipo de tabla hash Valores asociados Claves equivalentesstd unordered set No Nostd unordered multiset No Sistd unordered map Si Nostd unordered multimap Si NoLas nuevas clases satisfacen todos los requisitos de una clase container y tienen todos los metodos necesarios para acceder elementos insert erase begin end Esta nueva utilidad no necesita ninguna extension del nucleo del lenguaje de C solamente una pequena extension del encabezado lt functional gt y la introduccion de encabezados lt unordered set gt y lt unordered map gt aunque la implementacion tomara ventajas de varias caracteristicas del lenguaje C 11 No son necesarios otros cambios a cualquier clase estandar existente y no depende de ninguna de las otras extensiones de la biblioteca estandar Expresiones regulares Editar Muchas bibliotecas estandarizadas fueron creadas para manejar expresiones regulares Puesto que el uso de estos algoritmos es muy comun la biblioteca estandar los incluira usando todas las potencialidades de un lenguaje orientado a objetos La nueva biblioteca definida en el nuevo encabezado lt regex gt esta hecha de un par de clases Las expresiones regulares son representadas por la instancia de la clase de plantilla std regex Las ocurrencias son representadas por la instancia de la clase de plantilla std match results La funcion std regex search es usada para buscar mientras que para busqueda y reemplazo es usada la funcion std regex replace la cual retorna un nuevo string Los algoritmos std regex search y std regex replace toman una expresion regular y un string y escriben las ocurrencias encontradas en la estructura std match results Aqui hay un ejemplo en el uso del std match results const char reg esp t n List of separator characters this can be done using raw string literals const char reg esp R t n std regex rgx reg esp regex es una instancia de la clase de template basic regex con argumento de tipo char std cmatch match cmatch es una instancia de la clase de template match results con argumento de tipo const char const char target Unseen University Ankh Morpork Identifies all words of target separated by characters of reg esp if std regex search target match rgx If words separated by specified characters are present const size t n match size for size t a 0 a lt n a std string str match a first match a second std cout lt lt str lt lt n Note que se usan dobles barras inversas debido a que C usa la barra inversa simple como un caracter de escape La caracteristica raw string del C 11 pudiera usarse para evitar este problema La biblioteca lt regex gt no requiere ni la alteracion de cualquier encabezado existente aunque los usara cuando sea apropiado ni una extension del nucleo del lenguaje Punteros inteligentes de proposito general Editar Articulo principal Puntero inteligente C 11 proporciona el std unique ptr como tambien mejoras al std shared ptr y std weak ptr del TR1 std auto ptr es obsoleto Facilidad de numero random extensible Editar La biblioteca estandar de C proporciona la capacidad de generar numeros pseudaleatorios random a traves de la funcion rand Sin embargo el algoritmo es delegado enteramente al proveedor de la biblioteca C heredo esta funcionalidad sin cambios pero C 11 proporcionara un nuevo metodo para generar numeros pseudaleatorios La funcionalidad del numero al azar random de C 11 esta dividida en dos partes un motor generador que contiene el estado del generador de numero al azar y produce los numeros pseudaleatorios y una distribucion que determina el rango y la distribucion matematica del resultado Estos dos son combinados para formar un objeto generador de numeros al azar A diferencia del rand estandar de C el mecanismo del C 11 vendra con tres algoritmos de motor generador cada uno con sus propias fuerzas y debilidades Plantilla de clase Entero Punto flotante Calidad Velocidad Tamano del estadolinear congruential Entero Mediana Mediana 1subtract with carry Ambos Mediana Rapida 25 a href Mersenne twister html title Mersenne twister mersenne twister a Entero Buena Rapida 624C 11 tambien proporcionara un numero de distribuciones estandar a href Distribuci C3 B3n uniforme discreta html title Distribucion uniforme discreta uniform int distribution a a href Distribuci C3 B3n de Bernoulli html class mw redirect title Distribucion de Bernoulli bernoulli distribution a a href Distribuci C3 B3n geom C3 A9trica html title Distribucion geometrica geometric distribution a a href Distribuci C3 B3n de Poisson html title Distribucion de Poisson poisson distribution a a href Distribuci C3 B3n binomial html title Distribucion binomial binomial distribution a a href Distribuci C3 B3n uniforme continua html title Distribucion uniforme continua uniform real distribution a a href Distribuci C3 B3n exponencial html title Distribucion exponencial exponential distribution a a href Distribuci C3 B3n normal html title Distribucion normal normal distribution a y a href Distribuci C3 B3n gamma html title Distribucion gamma gamma distribution a El generador y las distribuciones son combinados como en el ejemplo siguiente include lt random gt include lt functional gt std uniform int distribution lt int gt distribution 0 99 std mt19937 engine Mersenne twister MT19937 auto generator std bind distribution engine int random generator Genera una variable entera uniforme entre 0 y 99 int random2 distribution engine Genera otra muestra usando directamente los objetos distribution y engine Referencia wrapper Editar Una referencia wrapper envoltura es obtenida de una instancia de la clase de plantilla reference wrapper Las referencias wrapper son similares a las referencias normales amp del lenguaje C Para obtener una referencia wrapper de cualquier objeto es usada la referencia de plantilla de funcion ref para una referencia constante es usado cref Las referencias wrapper son utiles sobre todo para las plantillas de funcion donde son necesarias las referencias a los parametros en vez de a las copias Esta funcion obtendra una referencia al parametro r y lo incrementara void f int amp r r Funcion de template template lt class F class P gt void g F f P t f t int main int i 0 g f i Es instanciado g lt void int amp r int gt entonces i no sera modificado std cout lt lt i lt lt std endl Salida gt 0 g f std ref i Es instanciado g lt void int amp r reference wrapper lt int gt gt entonces i sera modificado std cout lt lt i lt lt std endl Salida gt 1 Esta nueva utilidad sera agregada al encabezado existente lt utility gt y no necesita otras extensiones del lenguaje C Envoltorios polimorficos para objetos de funcion Editar Los envoltorios polimorficos para los objetos de funcion son similares a los punteros de funcion en la semantica y la sintaxis pero son menos fuertemente enlazados tightly bound y pueden referir indiscriminadamente cualquier cosa que puede ser llamada punteros de funcion punteros de miembro de funcion o functors cuyos argumentos son compatibles con las del envoltorio Con el ejemplo es posible entender sus caracteristicas std function lt int int int gt func Creacion de envoltorio wrapper usando la clase de plantilla function std plus lt int gt add plus es declarado como template lt class T gt T plus T T entonces add es de tipo int add int x int y func amp add OK Los parametros y el tipo de retorno son el mismo int a func 1 2 NOTA si el envoltorio func no se refiere a ninguna funcion es lanzada la excepcion std bad function call std function lt bool short short gt func2 if func2 Verdadero porque a func2 todavia no se le ha asignado una funcion bool adjacent long x long y func2 amp adjacent OK Los parametros y los tipos de retorno son convertibles struct Test bool operator short x short y Test car func std ref car std ref es una funcion de plantilla que retorna el envoltorio de funcion de miembro operator de struct car func func2 OK Los parametros y los tipos de retorno son convertibles La funcion de clase de plantilla sera definida dentro del encabezado lt functional gt y no requiere ningun cambio al lenguaje C Type traits para metaprogramacion Editar La metaprogramacion consiste en crear un programa que crea o modifica otro programa o a si mismo Esto puede suceder durante la compilacion o durante la ejecucion El comite de estandares de C ha decidido introducir una biblioteca que permite la metaprogramacion durante la compilacion a traves de plantillas Aqui hay un ejemplo de un meta programa usando el estandar actual de C 03 una recursion de instancias de plantillas para calcular exponentes enteros template lt int B int N gt struct Pow llamada recursiva y recombinacion enum value B Pow lt B N 1 gt value template lt int B gt struct Pow lt B 0 gt N 0 condicion de terminacion enum value 1 int quartic of three Pow lt 3 4 gt value Muchos algoritmos pueden operar en diferentes tipos de datos Las plantillas de C soportan la programacion generica y hacen el codigo mas compacto y util Sin embargo es comun para los algoritmos necesitar informacion sobre los tipos de datos que son usados Esta informacion puede ser extraida durante la instanciacion de una clase de plantilla usando type traits El type traits puede identificar la categoria de un objeto y todas las caracteristicas de una clase o de un struct Son definidos en el nuevo encabezado lt type traits gt En el ejemplo siguiente esta la funcion de plantilla elaborate que dependiendo de los tipos de datos dados instanciara uno de los dos algoritmos propuestos algorithm do it Primera forma de operar template lt bool B gt struct Algorithm template lt class T1 class T2 gt static int do it T1 amp T2 amp Segunda forma de operar template lt gt struct Algorithm lt true gt template lt class T1 class T2 gt static int do it T1 T2 Instanciando elaborate instanciara automaticamente la forma correcta de operar template lt class T1 class T2 gt int elaborate T1 A T2 B Usa la segunda forma solo si T1 es un entero y si T2 esta en punto flotante de lo contrario usa la primera forma return Algorithm lt std is integral lt T1 gt value amp amp std is floating point lt T2 gt value gt do it A B A traves del type traits definido en encabezado lt type transform gt es tambien posible crear operaciones de transformacion de tipos static cast y const cast son insuficientes dentro de una plantilla Este tipo de programacion produce un codigo elegante y conciso sin embargo el punto debil de estas tecnicas es la depuracion incomodo durante la compilacion y muy dificil durante la ejecucion del programa Metodo uniforme para computar el tipo de retorno de objetos de funcion Editar La determinacion del tipo de retorno de un objeto de funcion de plantilla en tiempo de compilacion no es intuitiva particularmente si el valor de retorno depende de los parametros de la funcion Como un ejemplo struct Clear int operator int El tipo del parametro es double operator double igual al tipo de retorno template lt class Obj gt class Calculus public template lt class Arg gt Arg operator Arg amp a const return member a private Obj member Instanciar la plantilla de clase Calculus lt Clear gt el objeto de funcion de calculus tendra siempre el mismo tipo de retorno que el objeto de funcion de Clear Sin embargo dada la clase Confused de abajo struct Confused double operator int El tipo del parametro NO es int operator double igual al tipo de retorno El intentar instanciar Calculus lt Confused gt causara que el tipo de retorno de Calculus no sea igual que el de clase Confused El compilador puede generar advertencias acerca de la conversion desde int a double y viceversa El TR1 introduce y C 11 adopta la clase de plantilla std result of que permite que uno determine y que use el tipo de retorno de un objeto de funcion para cada declaracion El objeto CalculusVer2 usa al objeto std result of para derivar el tipo de retorno del objeto de funcion template lt class Obj gt class CalculusVer2 public template lt class Arg gt typename std result of lt Obj Arg gt type operator Arg amp a const return member a private Obj member De esta manera en instancias del objeto de funcion CalculusVer2 lt Confused gt no hay conversiones advertencias o errores El unico cambio de la version TR1 del std result of es que la version TR1 permitia a una implementacion fallar para poder determinar el tipo del resultado de una llamada de funcion Debido a los cambios a C para soportar decltype la version C 11 del std result of ya no necesita estos casos especiales son requeridas las implementaciones para computar un tipo en todos los casos Caracteristicas eliminadas u obsoletas EditarMovidas a otro reporte Modulos Tipos Decimales Funciones Matematicas EspecialesPospuestas Conceptos Recolector de basura mas completo o requerido Reflexion Ambitos de macroCaracteristicas eliminadas u obsoletas EditarEl termino punto de secuencia que sera reemplazado al especificar que una operacion es secuenciada despues de otra o que dos operaciones no son secuenciales 8 Especificaciones de excepciones dinamicas Con la palabra clave noexcept esta disponible la especificacion en tiempo de compilacion de no excepcion lanzando funciones util para optimizacion std auto ptr Reemplazado por std unique ptr Clases base de funcion objeto std unary function std binary function adaptadores a punteros a funciones u adaptadores a punteros a miembros clases binder Lectura adicional EditarDocumentos del Comite de Estandar de C Editar Doc No 1401 Jan Kristoffersen 21 October 2002 Atomic operations with multi threaded environments Doc No 1402 Doug Gregor 22 October 2002 A Proposal to add a Polymorphic Function Object Wrapper to the Standard Library Doc No 1403 Doug Gregor 8 November 2002 Proposal for adding tuple types into the standard library Doc No 1424 John Maddock 3 March 2003 A Proposal to add Type Traits to the Standard Library Doc No 1429 John Maddock 3 March 2003 A Proposal to add Regular Expression to the Standard Library Doc No 1449 B Stroustrup G Dos Reis Mat Marcus Walter E Brown Herb Sutter 7 April 2003 Proposal to add template aliases to C Doc No 1450 P Dimov B Dawes G Colvin 27 March 2003 A Proposal to Add General Purpose Smart Pointers to the Library Technical Report Revision 1 Doc No 1452 Jens Maurer 10 April 2003 A Proposal to Add an Extensible Random Number Facility to the Standard Library Revision 2 Doc No 1453 D Gregor P Dimov 9 April 2003 A proposal to add a reference wrapper to the standard library revision 1 Doc No 1454 Douglas Gregor P Dimov 9 April 2003 A uniform method for computing function object return types revision 1 Doc No 1456 Matthew Austern 9 April 2003 A Proposal to Add Hash Tables to the Standard Library revision 4 Doc No 1471 Daveed Vandevoorde 18 April 2003 Reflective Metaprogramming in C Doc No 1676 Bronek Kozicki 9 September 2004 Non member overloaded copy assignment operator Doc No 1704 Douglas Gregor Jaakko Jarvi Gary Powell 10 September 2004 Variadic Templates Exploring the Design Space Doc No 1705 J Jarvi B Stroustrup D Gregor J Siek G Dos Reis 12 September 2004 Decltype and auto Doc No 1717 Francis Glassborow Lois Goldthwaite 5 November 2004 explicit class and default definitions Doc No 1719 Herb Sutter David E Miller 21 October 2004 Strongly Typed Enums revision 1 Doc No 1720 R Klarer J Maddock B Dawes H Hinnant 20 October 2004 Proposal to Add Static Assertions to the Core Language Revision 3 Doc No 1757 Daveed Vandevoorde 14 de enero de 2005 Right Angle Brackets Revision 2 Doc No 1811 J Stephen Adamczyk 29 April 2005 Adding the long long type to C Revision 3 Doc No 1815 Lawrence Crowl 2 May 2005 ISO C Strategic Plan for Multithreading Doc No 1827 Chris Uzdavinis Alisdair Meredith 29 August 2005 An Explicit Override Syntax for C Doc No 1834 Detlef Vollmann 24 June 2005 A Pleading for Reasonable Parallel Processing Support in C Doc No 1836 ISO IEC DTR 19768 24 June 2005 Draft Technical Report on C Library Extensions Doc No 1886 Gabriel Dos Reis Bjarne Stroustrup 20 October 2005 Specifying C concepts Doc No 1891 Walter E Brown 18 October 2005 Progress toward Opaque Typedefs for C 0X Doc No 1898 Michel Michaud Michael Wong 6 October 2004 Forwarding and inherited constructors Doc No 1919 Bjarne Stroustrup Gabriel Dos Reis 11 December 2005 Initializer lists Doc No 1968 V Samko J Willcock J Jarvi D Gregor A Lumsdaine 26 February 2006 Lambda expressions and closures for C Doc No 1986 Herb Sutter Francis Glassborow 6 April 2006 Delegating Constructors revision 3 Doc No 2016 Hans Boehm Nick Maclaren 21 April 2002 Should volatile Acquire Atomicity and Thread Visibility Semantics Doc No 2142 ISO IEC DTR 19768 12 de enero de 2007 State of C Evolution between Portland and Oxford 2007 Meetings Doc No 2228 ISO IEC DTR 19768 3 May 2007 State of C Evolution Oxford 2007 Meetings Doc No 2258 G Dos Reis and B Stroustrup Templates Aliases Doc No 2280 Lawrence Crowl 2 May 2007 Thread Local Storage Doc No 2291 ISO IEC DTR 19768 25 June 2007 State of C Evolution Toronto 2007 Meetings Doc No 2336 ISO IEC DTR 19768 29 July 2007 State of C Evolution Toronto 2007 Meetings Doc No 2389 ISO IEC DTR 19768 7 August 2007 State of C Evolution pre Kona 2007 Meetings Doc No 2431 SC22 WG21 N2431 J16 07 0301 2 October 2007 A name for the null pointer nullptr Doc No 2432 ISO IEC DTR 19768 23 October 2007 State of C Evolution post Kona 2007 Meeting Doc No 2437 Lois Goldthwaite 5 October 2007 Explicit Conversion Operators Doc No 2461 ISO IEC DTR 19768 22 October 2007 Working Draft Standard for programming Language C Doc No 2507 ISO IEC DTR 19768 4 February 2008 State of C Evolution pre Bellevue 2008 Meeting Doc No 2565 ISO IEC DTR 19768 7 March 2008 State of C Evolution post Bellevue 2008 Meeting Doc No 2597 ISO IEC DTR 19768 29 April 2008 State of C Evolution pre Antipolis 2008 Meeting Doc No 2606 ISO IEC DTR 19768 19 May 2008 Working Draft Standard for Programming Language C Doc No 2798 ISO IEC DTR 19768 4 October 2008 Working Draft Standard for Programming Language C Doc No 2857 ISO IEC DTR 19768 23 March 2009 Working Draft Standard for Programming Language C Doc No 2869 ISO IEC DTR 19768 28 April 2009 State of C Evolution post San Francisco 2008 Meeting Doc No 3014 Stephen D Clamage 4 November 2009 AGENDA PL22 16 Meeting No 53 WG21 Meeting No 48 8 13 March 2010 Pittsburgh PA Doc No 3082 Herb Sutter 13 March 2010 C 0x Meeting Schedule Doc No 3092 ISO ISC DTR 19769 26 March 2010 Working Draft Standard for Programming Language C Doc No 3126 ISO ISC DTR 19769 21 August 2010 Working Draft Standard for Programming Language C Doc No 3225 ISO ISC DTR 19769 27 November 2010 Working Draft Standard for Programming Language C Doc No 3242 ISO ISC DTR 19769 28 February 2011 Working Draft Standard for Programming Language C Doc No 3291 ISO ISC DTR 19769 5 April 2011 Working Draft Standard for Programming Language C Doc No 3290 ISO ISC DTR 19769 5 April 2011 FDIS Standard for Programming Language C Articulos Editar Bjarne Stroustrup 1 de mayo de 2005 The Design of C 0x Reinforcing C s proven strengths while moving into the future C C Users Journal Consultado el 23 de marzo de 2009 Raffaele Rialdi 16 de septiembre de 2005 Il futuro di C raccontato da Herb Sutter Web Log di Raffaele Rialdi Consultado el 23 de marzo de 2009 Danny Kalev 21 de julio de 2006 The Explicit Conversion Operators Proposal InformIT Archivado desde el original el 22 de octubre de 2012 Consultado el 23 de marzo de 2009 Danny Kalev 11 de julio de 2008 Lambda Expressions and Closures InformIT Archivado desde el original el 16 de septiembre de 2008 Consultado el 23 de marzo de 2009 Pete Becker 11 de abril de 2006 Regular Expressions Dr Dobb s Portal Consultado el 23 de marzo de 2009 Danny Kalev 10 de marzo de 2006 The Type Traits Library InformIT Archivado desde el original el 9 de abril de 2008 Consultado el 23 de marzo de 2009 Pete Becker 1 de mayo de 2005 C Function Objects in TR Getting from TR1 back to the Standard Library Dr Dobb s Portal Consultado el 23 de marzo de 2009 Howard E Hinnant Bjarne Stroustrup and Bronek Kozicki 10 de marzo de 2008 A Brief Introduction to Rvalue References The C Source Consultado el 23 de marzo de 2009 C 0x The Dawning of a New Standard DevX 18 de agosto de 2008 Consultado el 23 de marzo de 2009 Static code analysis and the new language standard C 0x Intel Software Network 15 de abril de 2010 Archivado desde el original el 14 de agosto de 2011 Bjarne Stroustrup August 2009 No Concepts in C 0x accu org Consultado el 29 de junio de 2010 Explicating the new C standard C 0x and its implementation in VC10 CodeProject com 8 de abril de 2010 Consultado el 13 de febrero de 2011 Vease tambien EditarC 14 C 17Notas EditarReferencias Editar Doc No 2697 ISO IEC DTR 19768 15 June 2008 Minutes of WG21 Meeting 8 15 June 2008 Doc No 2544 Alan Talbot Lois Goldthwaite Lawrence Crowl Jens Maurer 29 February 2008 Unrestricted unions Doc No 3000 ISO ISC DTR 19769 9 November 2009 Working Draft Standard for Programming Language C ISO IEC 2003 ISO IEC 14882 2003 E Programming Languages C 3 2 One definition rule basic def odr para 3 http gcc gnu org onlinedocs gcc Long Long html http msdn microsoft com en us library s3f49ktz VS 80 aspx Milewski Bartosz 3 de marzo de 2009 Broken promises C 0x futures Consultado el 24 de enero de 2010 Caves Jonathan 4 de junio de 2007 Update on the C 0x Language Standard Consultado el 25 de mayo de 2010 Enlaces externos EditarThe C Standards Committee comite encargado de los estandares del lenguaje C en ingles Bjarne Stroustrup s homepage pagina personal del creador de C con informacion sobre la evolucion del lenguaje en ingles Boost C Libraries C 0X The New Face of Standard C Herb Sutter s blog coverage of C 0x Anthony Williams blog coverage of C 0x A talk on C 0x given by Bjarne Stroustrup at the University of Waterloo The State of the Language An Interview with Bjarne Stroustrup 15 August 2008 Wiki page to help keep track of C 0x core language features and their availability in compilers Online C 11 standard library reference Datos Q1061570Obtenido de https es wikipedia org w index php title C 2B 2B11 amp oldid 138820326, wikipedia, wiki, leyendo, leer, libro, biblioteca,

español

, española, descargar, gratis, descargar gratis, mp3, video, mp4, 3gp, jpg, jpeg, gif, png, imagen, música, canción, película, libro, juego, juegos