c++ compiler-errors g++

c++ - ¿Por qué vector<bool>:: reference no devuelve referencia a bool?



compiler-errors g++ (6)

#include <vector> struct A { void foo(){} }; template< typename T > void callIfToggled( bool v1, bool &v2, T & t ) { if ( v1 != v2 ) { v2 = v1; t.foo(); } } int main() { std::vector< bool > v= { false, true, false }; const bool f = false; A a; callIfToggled( f, v[0], a ); callIfToggled( f, v[1], a ); callIfToggled( f, v[2], a ); }

La compilación del ejemplo anterior produce el próximo error:

dk2.cpp: In function ''int main()'': dk2.cpp:29:28: error: no matching function for call to ''callIfToggled(const bool&, std::vector<bool>::reference, A&)'' dk2.cpp:29:28: note: candidate is: dk2.cpp:13:6: note: template<class T> void callIfToggled(bool, bool&, T&)

Compilé usando g ++ (versión 4.6.1) de esta manera:

g++ -O3 -std=c++0x -Wall -Wextra -pedantic dk2.cpp

La pregunta es por qué sucede esto? ¿El vector<bool>::reference no bool& ? ¿O es un error del compilador?
¿O estoy intentando algo estúpido? :)


Haz una estructura con un bool y haz que el vector<> use ese tipo de estructura.

Tratar:

vector<struct sb> donde sb es struct {boolean b];

entonces puedes decir

push_back({true})

hacer

typedef struct sbool {bool b;} boolstruct; y luego vector<boolstruct> bs;


Solo mis 2 centavos:

std::vector<bool>::reference es un typedef para struct _Bit_reference que se define como

typedef unsigned long _Bit_type; struct _Bit_reference { _Bit_type * _M_p; _Bit_type _M_mask; // constructors, operators, etc... operator bool() const { return !!(*_M_p & _M_mask); } };

Cambiando la función de esta manera, funciona (bueno, compila al menos, no ha probado):

template< typename T > void callIfToggled( bool v1, std::vector<bool>::reference v2, T & t ) { bool b = v2; if ( v1 != b ) { v2 = v1; t.foo(); } }

EDITAR: Cambié la condición de (v1! = V2), que no era una buena idea, a (v1! = B).


Sus expectativas son normales, pero el problema es que std::vector<bool> ha sido un tipo de experimento por parte del comité de C ++. En realidad, se trata de una especialización de plantillas que almacena los valores de bool empaquetados en la memoria: un bit por valor.

Y como no puedes tener una referencia un poco, ahí está tu problema.


Vector está especializado para bool .

Se considera un error de la norma. Use vector<char> lugar:

template<typename t> struct foo { using type = t; }; template<> struct foo<bool> { using type = char; }; template<typename t, typename... p> using fixed_vector = std::vector<typename foo<t>::type, p...>;

Ocasionalmente puede necesitar referencias a un bool contenido dentro del vector. Desafortunadamente, usar vector<char> solo puede darle referencias a caracteres. Si realmente necesitas bool& , echa un vistazo a la biblioteca de Boost Containers . Tiene una versión no especializada de vector<bool> .


std::vector< bool > empaqueta sus contenidos para que cada valor booleano se almacene en un bit, ocho bits en un byte. Esto es eficiente desde el punto de vista de la memoria, pero computacionalmente intensivo, ya que el procesador debe realizar operaciones aritméticas para acceder al bit solicitado. Y no funciona con referencia de bool o semántica de puntero, ya que los bits dentro de un byte no tienen direcciones en el modelo de objetos de C ++.

Aún puede declarar una variable de tipo std::vector<bool>::reference y usarla como si fuera bool& . Esto permite que los algoritmos genéricos sean compatibles.

std::vector< bool > bitvec( 22 ); std::vector< bool >::reference third = bitvec[ 2 ]; third = true; // assign value to referenced bit

En C ++ 11, puede solucionar esto utilizando auto y el especificador && que selecciona automáticamente una referencia lvalue vinculada al elemento vectorial o una referencia rvalue vinculada a un temporal.

std::vector< bool > bitvec( 22 ); auto &&third = bitvec[ 2 ]; // obtain a std::vector< bool >::reference third = true; // assign value to referenced bit