We have this example:
struct X {
int e0 : 6;
int e1 : 6;
int e2 : 6;
...
int e10 : 6;
};
struct X c;
How can开发者_JS百科 I access the members "automatically", something like that:
c.e{0-10} ? Say if I want to read c.e0, then c.e1 ... If my struct would have 1000 elements, I do not think that I should write so much code, right ?Can you help me with a workaround, an idea ?
I mention that I already read other posts related somehow to this problem, but I did not find a solution.Thank you very much !
As others have said, you cannot do exactly what you want with bit fields. It looks like you want to store a large number of 6 bit integers with maximum space efficiency. I will not argue whether this is a good idea or not. Instead I will present an old-school C like way of doing exactly that, using C++ features for encapsulation (untested). The idea is that 4 6 bit integers require 24 bits, or 3 characters.
// In each group of 3 chars store 4 6 bit ints
const int nbr_elements = 1000;
struct X
{
// 1,2,3 or 4 elements require 3 chars, 5,6,7,8 require 6 chars etc.
char[ 3*((nbr_elements-1)/4) + 3 ] storage;
int get( int idx );
};
int X::get( int idx )
{
int dat;
int offset = 3*(idx/4); // eg idx=0,1,2,3 -> 0 idx=4,5,6,7 -> 3 etc.
char a = storage[offset++];
char b = storage[offset++];
char c = storage[offset];
switch( idx%4) // bits lie like this; 00000011:11112222:22333333
{
case 0: dat = (a>>2)&0x3f; break;
case 1: dat = ((a<<4)&0x30) + ((b>>4)&0x0f); break;
case 2: dat = ((b<<2)&0x3c) + ((c>>6)&0x03); break;
case 3: dat = c&0x3f; break;
}
return dat;
}
I will leave the companion put() function as an exercise.
It sounds like a struct isn't the right tool for what you're trying to do. You need either an array or a vector. Arrays are used for storing a number of the same type of data. Vectors are array wrappers that manage the addition and removal of items automatically.
If you need a list of the same data, and some other data (say a string) you can make an array or a vector part of your struct.
struct X {
int[10] numbs;
string name;
};
X c;
You can't. To do this would require some form of reflection, which is not supported in either C or C++.
Since your bitfields are of the same size, you could encapsulate std::bitset
(or vector<bool>
, gulp...) and provide your own iterators (each increment moving the bookmark six bits) and operator[]
(etc) to allow your code to be more simple to write.
I am sure performance would suck compared to the bitfields though.
How about something like this:
char getByte(char *startPos, int index) {
int i = (index*6) / 8;
if (index % 4 == 0)
return 0b11111100 & startPos[i] >> 2;
else if (index % 4 == 3)
return 0b00111111 & startPos[i];
else if (index % 4 == 2)
return (0b00001111 & startPos[i] << 2) | (0b11000000 & startPos[i+1] >> 6);
else
return (0b00000011 & startPos[i] << 4) | (0b11110000 & startPos[i+1] >> 4);
}
精彩评论