vectores programacion matrices llenar imprimir funciones ejemplos declarar con como c++ c++11 initializer-list uniform-initialization

c++ - programacion - vectores en c



¿Por qué ''std:: vector<int> b{2};'' crear un vector de 1 elemento, y no uno de 2 elementos? (3)

La norma establece que el constructor de lista de inicializadores tiene prioridad sobre los demás. Este es solo un caso en el que no es posible simplemente reemplazar () con {} . Hay otros, por ejemplo {} inicialización no permite reducir las conversiones.

He estado jugando con C ++ 11 durante los últimos días, y se me ocurrió algo extraño.

Si quiero inicializar uniformemente un int:

int a{5};

Pero si hago lo mismo con un std :: vector:

std::vector<int> b{2};

No construye una matriz de dos elementos, sino una matriz con un elemento de valor dos. Parece que para obtener ese efecto uno debería ser más explícito al respecto:

std::vector<int> c{{2}}; std::vector<int> d = {2};

Pero no como la declaración de b: esto parece inconsistente. He visto otras cosas con el mismo efecto. Lo que estoy preguntando es: ¿este comportamiento está en el estándar final C ++ 11, o es solo en un borrador que se implementó temprano? Si es así, ¿por qué el comité de estándares incluye este comportamiento? Parece que esto frustra el propósito total de la inicialización uniforme, ya que uno tiene que recordar qué clases tienen constructores de listas de inicializadores, y usar la sintaxis old () en lugar de {} solo con esas clases. O uno renuncia por completo a la inicialización uniforme.

Esto parece un gran "gotcha". Pero puede haber ventajas que no conozco.

Editar: este código:

#include <iostream> #include <vector> int main() { std::vector<int> a{2}; for (auto x: a) { std::cout << x << std::endl; } return 0; }

salidas "2" en gcc 4.6.2


La inicialización uniforme no significa lo que crees que hace. Se agregó para hacer que la inicialización sea más uniforme entre los tipos en C ++. El razonamiento es este:

typedef struct dog_ { float height; int weight; } dog; int main() { dog Spot = { 25.6, 45}; dog Data[3] = { Spot, {6.5, 7} }; std::array<dog, 2> data = { { Spot, {6.5, 7} } }; //only in C++ obviously return 0; }

Este es un código válido de C y C ++ , y lo ha sido por muchos años . Fue muy conveniente, pero tenía que recordar que esto solo funcionaba con los tipos de POD. La gente se ha quejado durante mucho tiempo de que no hay forma de hacer std::vector<int> data = { 3, 7, 4, 1, 8}; , pero algunas clases ( std::array ) se escribieron de maneras extrañas para permitir constructores de listas de inicializadores.

Así que para C ++ 11, el comité lo hizo para que pudiéramos hacer que los vectores y otras clases geniales también lo hicieran. Esto hizo que la construcción de todos los tipos sea más uniforme, por lo que podemos usar {} para inicializar a través de constructores, y también de listas de valores. El problema al que se está enfrentando es que la sobrecarga del constructor con std::initializer_list<int> es la mejor coincidencia, y se seleccionará primero. Como tal, std::vector<int> b{2}; no significa llamar al constructor que toma un int , sino que significa crear un vector partir de esta lista de valores int . En esa luz, tiene perfecto sentido crear un vector contenga un valor único de 2 . Para llamar a un constructor diferente, deberá usar la sintaxis () para que C ++ sepa que no desea inicializar desde una lista.


Sí, este comportamiento está destinado, de acuerdo con §13.3.1.7 Inicialización por inicialización de lista

Cuando los objetos del tipo de clase no agregada T se inicializan en la lista (8.5.4), la resolución de sobrecarga selecciona el constructor en dos fases:

- Inicialmente, las funciones candidatas son los constructores de lista de inicializadores (8.5.4) de la clase T y la lista de argumentos consta de la lista de inicializadores como un único argumento.

- Si no se encuentra un constructor viable de listas de inicializadores, la resolución de sobrecarga se realiza nuevamente, donde las funciones candidatas son todos los constructores de la clase T y la lista de argumentos consta de los elementos de la lista de inicializadores.

En cuanto a "todo el propósito de la inicialización uniforme" ... "Inicialización uniforme" es un término de marketing, y no una muy buena descripción. El estándar tiene todas las formas habituales de inicialización más inicialización de listas, pero no una "inicialización uniforme". La inicialización de listas no pretende ser la forma definitiva de inicialización, es solo otra herramienta en el cinturón de herramientas.