instead - for auto p m c++
Range-for-loops y std:: vector<bool> (3)
¡Porque std::vector<bool>
no es un contenedor !
std::vector<T>
iteradores de std::vector<T>
suelen desreferenciar a un T&
, que puede vincular a su propio auto&
.
std::vector<bool>
, sin embargo, agrupa sus bool
dentro de enteros, por lo que necesita un proxy para enmascarar los bits al acceder a ellos. Por lo tanto, sus iteradores devuelven un Proxy
.
Y dado que el Proxy
devuelto es un prvalue (un temporal), no puede vincularse a una referencia lvalue como auto&
.
La solución: use auto&&
, que colapsará correctamente en una referencia lvalue si se le da una, o enlazará y mantendrá el temporal activo si recibe un proxy.
Por qué funciona este código
std::vector<int> intVector(10);
for(auto& i : intVector)
std::cout << i;
Y esto no?
std::vector<bool> boolVector(10);
for(auto& i : boolVector)
std::cout << i;
En este último caso, recibo un error
error: inicialización no válida de la referencia no const del tipo ''std :: _ Bit_reference &'' de un valor de r ''del tipo'' std :: _ Bit_iterator :: reference {alias std :: _ Bit_reference} ''
for(auto& i : boolVector)
vector<bool>
se (generalmente) se especializa explícitamente para almacenar cada bool
en un solo bit , reduciendo los costos de almacenamiento de un byte por valor a un byte por cada ocho valores. Ningún procesador que conozco de forma manual es direccionable, por lo que es imposible almacenar una referencia a los valores en el vector<bool>
. Debe usar auto
simple, no auto&
para el valor de iteración i
.
std::vector<bool>
no obedece las reglas estándar del contenedor.
En particular, su operator[]
no devuelve bool&
.
El ciclo en el código inválido
#include <vector>
#include <iostream>
int main() {
std::vector<bool> boolVector(10);
for (auto& i: boolVector)
std::cout << i;
}
puede reescribirse en cualquiera de las tres formas de recorrer los valores:
(solo lectura)
for (auto i: boolVector) std::cout << i;
(solo lectura, posiblemente ineficiente)
for (auto const& i: boolVector) std::cout << i;
(leer escribir)
for (auto&& i: boolVector) std::cout << i;
La elección entre el primero y el último depende de si necesita modificar los valores en el vector o simplemente leerlos.