example - vector initialization c++
Alternativa al vector<bool> (7)
Como (con suerte) todos sabemos, vector<bool>
está totalmente roto y no puede tratarse como una matriz de ca. ¿Cuál es la mejor manera de obtener esta funcionalidad? Hasta ahora, las ideas que he pensado son:
- Use un
vector<char>
lugar, o - Utilice una clase de contenedor y tenga
vector<bool_wrapper>
¿Cómo manejan ustedes este problema? Necesito la funcionalidad c_array ().
Como una pregunta complementaria, si no necesito el método c_array (), ¿cuál es la mejor manera de abordar este problema si necesito acceso aleatorio? ¿Debería usar un deque u otra cosa?
Editar:
- Necesito dimensionamiento dinámico.
- Para aquellos que no saben, el
vector<bool>
está especializado, de modo que cada bool toma 1 bit. Por lo tanto, no puede convertirlo a una matriz de estilo c. - Creo que "envoltorio" es un nombre poco apropiado. Estaba pensando algo como esto:
Por supuesto, entonces tengo que leer en my_bool debido a posibles problemas de alineación :(
struct my_bool
{
bool the_bool;
};
vector<my_bool> haha_i_tricked_you;
¿Cómo manejan ustedes este problema? Necesito la funcionalidad c_array ().
boost::container::vector<bool>
:
La especialización de vector < bool > ha sido bastante problemática, y ha habido varios intentos infructuosos para depreciarla o eliminarla del estándar.
Boost.Container
no lo implementa ya que hay una solución Boost.DynamicBitset superior....
Así que boost :: container :: vector :: iterator devuelve referencias bool reales y funciona como un contenedor totalmente compatible. Si necesita una versión optimizada de memoria de las funcionalidades boost :: container :: vector < bool >, use Boost.DynamicBitset .
Considere usar un vector <int>. Una vez que superas la compilación y la verificación de tipos, bool e int son palabras simples (edición: aparentemente esto no siempre es cierto, pero será cierto en muchas arquitecturas de PC). En los casos en que desee convertir sin advertencia, use "bool foo = !! bar", que convierte cero en falso y no cero en verdadero.
Un vector <char> o similar usará menos espacio, aunque también tiene el potencial de dar un golpe de velocidad (muy pequeño) en algunas circunstancias, porque los caracteres son menores que el tamaño de palabra de la máquina. Esta es, creo, la razón principal por la que los bools se implementan usando ints en lugar de caracteres.
Si realmente quieres una semántica limpia, también me gusta la sugerencia de crear tu propia clase booleana: parece un bool, actúa como un bool, pero engaña a la especialización de la plantilla.
Además, bienvenidos al club de personas que quieren que la especialización vectorial <bool> se elimine del estándar C ++ (con bit_vector para reemplazarla). Es donde todos los chicos cool pasan el rato :).
Depende de tus necesidades Yo elegiría std::vector<unsigned char>
. Escribir un contenedor puede estar bien si solo usa un subconjunto de la funcionalidad, sino se convertirá en una pesadilla.
Ese es un problema interesante.
Si necesita lo que hubiera sido un estándar :: std si no estaba especializado, entonces tal vez algo así funcionaría bien con su caso:
#include <vector>
#include <iostream>
#include <algorithm>
class Bool
{
public:
Bool(): m_value(){}
Bool( bool value ) : m_value(value){}
operator bool() const { return m_value;}
// the following operators are to allow bool* b = &v[0]; (v is a vector here).
bool* operator& () { return &m_value; }
const bool * const operator& () const { return &m_value; }
private:
bool m_value;
};
int main()
{
std::vector<Bool> working_solution(10, false);
working_solution[5] = true;
working_solution[7] = true;
for( int i = 0; i < working_solution.size(); ++i )
{
std::cout<< "Id " << i << " = " << working_solution[i] << "(" <<(working_solution[i] ? "true" : "false") << ")" <<std::endl; // i used ? : to be sure the boolean evaluation is correct
}
std::sort( working_solution.begin(), working_solution.end());
std::cout<< "--- SORTED! ---" << std::endl;
for( int i = 0; i < working_solution.size(); ++i )
{
bool* b = &working_solution[i]; // this works!
std::cout<< "Id " << i << " = " << working_solution[i] << "(" << (working_solution[i] ? "true" : "false") << ")" <<std::endl; // i used ? : to be sure the boolean evaluation is correct
}
std::cin.get();
return 0;
}
Intenté esto con VC9 y parece funcionar bien. La idea de la clase Bool es simular el tipo bool al proporcionar el mismo comportamiento y tamaño (pero no del mismo tipo). Casi todo el trabajo lo realiza el operador bool y los constructores de copia predeterminados aquí. Agregué un tipo para asegurarme de que reacciona como se supone al usar algoritmos.
No estoy seguro de que sea adecuado para todos los casos. Si es adecuado para sus necesidades, sería menos trabajo que reescribir una clase similar a un vector ...
Este problema ya fue discussed en comp.lang.c ++. Moderado. Soluciones propuestas:
- su propio asignador (basado en
std::allocator
) y su propia especialización vectorial; - use
std::deque
(como se recomendó anteriormente en uno de los libros de S. Mayers) - pero esto no es para sus requisitos; - hacer POD
bool
wrapper; - use algo (
char
/int
/ etc) con el mismo tamaño quebool
lugar debool
;
También desde el principio vi una propuesta para un comité estándar: introducir un macro (algo así como STD_VECTOR_BOOL_SPECIAL
) para rechazar esta especialización, pero AFAIK esta propuesta no se implementó en las implementaciones stl y no fue aprobada.
Parece que tu problema no tiene formas de hacerlo bien ... Tal vez en C ++ 0x.
La respuesta más simple es use vector<struct sb>
donde sb
es struct {boolean b};
. Entonces puedes decir push_back({true})
. Parece bien.
Use std::deque
si no necesita la matriz, sí.
De lo contrario, use un vector
alternativo que no se especialice en bool
, como el de Boost Container .