loop instead for based c++ c++11 for-loop range auto

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)



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:

  1. (solo lectura)

    for (auto i: boolVector) std::cout << i;

  2. (solo lectura, posiblemente ineficiente)

    for (auto const& i: boolVector) std::cout << i;

  3. (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.