2011-06-10 21 views
5

De http://www.cplusplus.com/reference/stl/bitset/:Bitset Referencia

porque no existe tal tipo pequeño elemental en la mayoría de entornos de C++, se accede a los elementos individuales como referencias especiales que imitan bool elementos.

¿Cómo funciona exactamente esta referencia de bit?

La única forma en que podría pensar sería usar una matriz estática de char s, pero cada instancia necesitaría almacenar su índice en la matriz. Dado que cada instancia de referencia tendría al menos el tamaño de size_t, eso destruiría la compacidad del conjunto de bits. Además, el cambio de tamaño puede ser lento y se espera que la manipulación de bits sea rápida.

Respuesta

5

Creo que estás confundiendo dos cosas.

La clase bitset almacena los bits en una representación compacta, p. Ej. en una matriz char, típicamente 8 bits por char (pero YMMV en plataformas "exóticas").

La clase bitset::reference se proporciona para permitir a los usuarios de la clase bitset tener objetos similares a los bits almacenados en un bitset.

Debido punteros regulares y referencias no tienen suficiente granularidad para apuntar a los bits individuales almacenados en los bitset (su granularidad mínima es la char), tales imita clase la semántica de una referencia a las operaciones de referencia similares a falsas lvalue en los bits. Esto es necesario, en particular, para permitir que el valor devuelto por operator[] funcione "normalmente" como valor l (y probablemente constituya el 99% de su uso "normal"). En este caso, se puede ver como un "proxy-objeto".

Este comportamiento se logra al sobrecargar el operador de asignación y el operador de conversión a bool; la clase bitset::reference probablemente encapsule una referencia al objeto padre bitset y el desplazamiento (bytes + bit) del bit al que se hace referencia, que utilizan dichos operadores para recuperar y almacenar el valor del bit.

--- --- EDITAR

En realidad, la aplicación g ++ hace que la tienda bitset::reference directamente un puntero a la palabra de memoria en la que se almacena el byte, y el número de bits en dicha palabra. Sin embargo, esto es solo un detalle de implementación para aumentar su rendimiento.

Por cierto, en las fuentes de la biblioteca encontré una explicación muy compacto, pero clara de lo que es bitset::reference y lo que hace:

/** 
    * This encapsulates the concept of a single bit. An instance of this 
    * class is a proxy for an actual bit; this way the individual bit 
    * operations are done as faster word-size bitwise instructions. 
    * 
    * Most users will never need to use this class directly; conversions 
    * to and from bool are automatic and should be transparent. Overloaded 
    * operators help to preserve the illusion. 
    * 
    * (On a typical system, this <em>bit %reference</em> is 64 
    * times the size of an actual bit. Ha.) 
    */ 
1

No he visto la fuente STL, pero esperaría que una referencia Bitset contuviera un puntero al conjunto de bits real, y un número de bit de tamaño size_t. Las referencias solo se crean cuando intenta obtener una referencia a un elemento bitset.

Es poco probable que el uso normal de bitsets use referencias extensamente (si es que lo hace), por lo que no debería haber un gran problema de rendimiento. Y, es conceptualmente similar a los tipos char. Una char es normalmente de 8 bits, pero para almacenar una 'referencia' a una char requiere un puntero, por lo general 32 o 64 bits.

0

nunca he mirado en la implementación de referencia, pero es obvio que debe conocer el conjunto de bits al que se refiere a través de una referencia, y el índice del bit que es responsable de cambiar. Luego puede usar el resto de la interfaz de los conjuntos de bits para realizar los cambios necesarios. Esto puede ser bastante eficiente. Note los bitsets no pueden ser redimensionados.

0

No estoy muy seguro de lo que está preguntando, pero puedo decirle una forma de acceder a bits individuales en un byte, que es quizás lo que hacen los bitsets. Tenga en cuenta que el siguiente código no es mío y es especificación de Microsoft (!).

Crear una estructura como tal:

struct Byte 
{ 
    bool bit1:1; 
    bool bit2:1; 
    bool bit3:1; 
    bool bit4:1; 
    bool bit5:1; 
    bool bit6:1; 
    bool bit7:1; 
    bool bit8:1; 
} 

El ': 1' parte de este código son campos de bits. http://msdn.microsoft.com/en-us/library/ewwyfdbe(v=vs.80).aspx Define cuántos bits desea que ocupe una variable, por lo que en esta estructura, hay 8 bools que ocupan 1 bit cada uno. En total, la estructura 'Byte' es por lo tanto de 1 byte de tamaño.

Ahora bien, si usted tiene un byte de datos, tales como un char, puede almacenar estos datos en un objeto de bytes de la siguiente manera:

char a = 'a'; 
Byte oneByte; 
oneByte = *(Byte*)(&a); // Get the address of a (a pointer, basically), cast this 
          // char* pointer to a Byte*, 
          // then use the reference operator to store the data that 
          // this points to in the variable oneByte. 

Ahora puede acceder (y modificar) los bits individuales accediendo las variables miembro de bool de oneByte. Con el fin de almacenar los datos alterados en un char de nuevo, puede hacerlo de la siguiente manera:

char b; 
b = *(char*)(&oneByte); // Basically, this is the reverse of what you do to 
          // store the char in a Byte. 

Voy a tratar de encontrar la fuente de esta técnica, para dar crédito a quien crédito merece.

También, de nuevo, no estoy del todo seguro de si esta respuesta es de alguna utilidad para usted. Interpreté su pregunta como '¿cómo se manejaría el acceso a bits individuales internamente?'.

+0

La pregunta es sobre las clases 'std :: bitset' y' std :: bitset :: reference' de la biblioteca estándar de C++. –

+0

@Matteo Italia: Sé tanto, interpreté la pregunta como si me preguntaran cómo se implementa internamente el acceso de estas clases a los bits. – Rycul

Cuestiones relacionadas