vectors example español c++ c++11 vector

example - ¿Por qué C++ 11 eliminó el valor predeterminado de los prototipos del constructor de relleno de std:: vector?



vector of vectors c++ (2)

El C ++ 98 tomó un objeto prototipo y luego lo copió n veces. Por defecto, el prototipo era un objeto construido por defecto.

La versión C ++ 11 construye n objetos construidos por defecto.

Esto elimina n copias y lo reemplaza con n construcciones por defecto. Además, evita construir el prototipo.

Supongamos que su clase se ve así:

struct bulky { std::vector<int> v; bulky():v(1000) {} // 1000 ints bulky(bulky const&)=default; bulky& operator=(bulky const&)=default; // in C++11, avoid ever having an empty vector to maintain // invariants: bulky(bulky&& o):bulky() { std::swap(v, o.v); } bulky& operator=(bulky&& o) { std::swap(v,o.v); return *this; } };

esta es una clase que siempre posee un buffer de 1000 int s.

si luego creamos un vector de bulky :

std::vector<bulky> v(2);

en C ++ 98 esto asignó 3 veces 1000 enteros. En C ++ 11 esto asignó solo 2 veces 1000 enteros.

Además, la versión C ++ 98 requiere que el tipo sea copiable. Hay tipos que no se pueden copiar en C ++ 11, como std::unique_ptr<T> , y no se puede generar un vector de punteros únicos construidos por defecto utilizando la firma C ++ 98. La firma C ++ 11 no tiene ningún problema con eso.

std::vector<std::unique_ptr<int>> v(100);

Lo anterior no funcionaría si aún tuviéramos la versión C ++ 98.

En C ++ 98, el prototipo para el constructor de relleno std::vector tiene un valor predeterminado para el inicializador.

explicit vector (size_type n, const value_type& val = value_type(), const allocator_type& alloc = allocator_type());

C ++ 11 usa dos prototipos.

explicit vector (size_type n); vector (size_type n, const value_type& val, const allocator_type& alloc = allocator_type());

(En C ++ 14 el constructor de relleno cambió de nuevo, pero no es el objetivo de esta pregunta).

Un enlace de referencia está here .

¿Por qué C ++ 11 value_type() valor de inicializador value_type() ?

Por cierto, traté de compilar el siguiente código con clang++ -std=c++11 y emitió un error, lo que significa que el tipo de valor todavía necesita tener un constructor predeterminado como S() {} , es decir, ser predeterminado-construible .

#include <vector> struct S { int k; S(int k) : k(k) {} // intentionally remove the synthesized default constructor }; int main() { std::vector<S> s(5); // error: no matching constructor }


La razón por la que el constructor se dividió en dos fue para admitir tipos de "solo movimiento" como unique_ptr<T> .

Este constructor:

vector(size_type n, const T& value, const Allocator& = Allocator());

requiere que T sea ​​copiable, porque n T s debe copiarse del value para poblar el vector .

Este constructor:

explicit vector(size_type n, const Allocator& = Allocator());

no requiere que T sea ​​copiable, solo constructivo predeterminado.

El último constructor funciona con unique_ptr<T> :

std::vector<std::unique_ptr<int>> s(5);

mientras que el antiguo constructor no.

Aquí está la propuesta que hizo este cambio: http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2005/n1858.html#23.2.4.1%20-%20vector%20constructors,%20copy,%20and%20assignment

Y este documento tiene algunos de los fundamentos, aunque es cierto que es un poco elocuente: http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2005/n1771.html

Fwiw, resize :

void resize(size_type sz, T c = T());

fue dividido en:

void resize(size_type sz); void resize(size_type sz, const T& c);

por la misma razón. El primero requiere constructable predeterminado pero no copiable construible (para admitir tipos predeterminados de movimiento solo construible), y el segundo requiere copiable.

Estos cambios no fueron 100% compatibles con versiones anteriores. Para algunos tipos (por ejemplo, punteros inteligentes contados de referencia), la construcción de copias a partir de un objeto construido por defecto no es lo mismo que la construcción predeterminada. Sin embargo, se consideró que el beneficio de admitir tipos de solo movimiento valía la pena el costo de esta rotura API.