2009-03-30 9 views
5

Dynamic bitsetajustes de intensificación dynamic_bitset de una cadena

tengo un caso de uso en las que necesito para poblar

boost::dynamic_bitset<unsigned char> , from a std::string buffer. 

Puede sugerir en cuanto a cómo ir sobre esto. Así que necesito para llegar a una función

void populateBitSet (std::string &buffer, 
      boost::dynamic_bitset<unsigned char> & bitMap) { 

    //populate bitMap from a string buffer 
} 
+0

Deberá especificar al menos cómo se debe interpretar la cadena. ¿Son los personajes '1' y '0' solamente y esos son los bits? ¿O es una representación hexadecimal? ¿O desea que el almacenamiento sin formato de los caracteres de cadena entre en el conjunto de bits? –

+0

¿El búfer de cadena está lleno de datos binarios o datos de cadena? Es decir. se inicializa así: string buffer = "1111101001010000"; o este string buffer = {0xfa, 0x50}; – Eclipse

+0

¿qué mismo buffer de cadena? es "01010111" o "asdfvfdsa"? – bayda

Respuesta

9

Si tiene datos binarios como este:

string buffer = "0101001111011"; 

desea inicializar como este (resulta que hay un constructor que maneja este caso):

void populateBitSet (std::string &buffer, boost::dynamic_bitset<unsigned char> & bitMap) 
{   
    bitMap = boost::dynamic_bitset<unsigned char> (buffer); 
} 

Si desea que los datos en bruto, utilice el iterator constructor:

void populateBitSet (std::string &buffer, boost::dynamic_bitset<unsigned char> & bitMap) 
{   
    bitMap = boost::dynamic_bitset<unsigned char> (buffer.begin(), buffer.end()); 
} 

Estos terminan asignando la memoria necesaria dos veces, por lo que puede que estés mejor con una asignación de pila y un intercambio. O simplemente puede esperar hasta C++ 0x y dejar que la semántica del movimiento haga lo suyo.

// Unecessary in C++0x 
void populateBitSet (std::string &buffer, boost::dynamic_bitset<unsigned char> & bitMap) 
{   
    boost::dynamic_bitset<unsigned char> localBitmap(buffer.begin(), buffer.end()); 
    bitMap.swap(localBitmap); 
} 

Editar: para aclarar por qué las primeras versiones asignan el doble de memoria:

Tome un vistazo a otra manera de escribir la primera versión:

typedef boost::dynamic_bitset<unsigned char> bits; // just to shorten the examples. 
void populateBitSet (std::string &buffer, bits &bitMap) 
{   
    const bits &temp = bits(buffer); // 1. initialize temporary 
    bitMap = temp; // 2. Copy over data from temp to bitMap 
} 

Si coloca estos dos líneas juntas, como en el primer ejemplo, aún se obtiene una construcción temporal en la pila, seguida de una asignación. En 1. boost necesita asignar suficiente memoria para todo el conjunto de bits. En 2, boost necesita asignar memoria suficiente para mantener el mismo conjunto de bits y luego copiar los valores. Es posible que bitMap ya tenga suficiente memoria, por lo que no siempre es necesario reasignarlo, pero también es posible que libere su memoria de respaldo y lo reasigne desde cero de todos modos.

La mayoría de los contenedores que se ajustan al molde stl también tienen una función de intercambio que puede utilizar en lugar de la asignación cuando tiene intención de tirar un lado del intercambio. Por lo general, son O (1) y no lanzan, ya que a menudo solo implican intercambiar algunos punteros. Consulte esto GotW por otro motivo por el cual estos son útiles.

En C++ 0X, podrá utilizar la asignación y aún así obtener las ventajas de swap. Como puede sobrecargar los valores r (como el temporal), el contenedor sabe que cuando asigna un temporal, sabe que puede canibalizar la temperatura y básicamente hacer un intercambio. El blog del equipo de Visual Studio ha cubierto los valores y la semántica de movimiento quite well here.

+0

Oye, Josh, no entiendo cuando dices que las versiones no intercambiables asignan la cosa dos veces ... ¿podrías explicar eso? ¡Gracias! –

Cuestiones relacionadas