C++ C++;:无法在按位函数之后将int类型设置为非标量
我有两个位字段:(1)一个用于处理帧(标头),(2)另一个用于处理帧内的子帧(IdentityField2M) 对于BitFieldMember模板,我在这里使用了这个非常有用的模板: 查看BitFieldMember模板的定义,下面是将值赋给字段的操作数=我怀疑这个问题可能出在哪里C++ C++;:无法在按位函数之后将int类型设置为非标量,c++,bit-fields,C++,Bit Fields,我有两个位字段:(1)一个用于处理帧(标头),(2)另一个用于处理帧内的子帧(IdentityField2M) 对于BitFieldMember模板,我在这里使用了这个非常有用的模板: 查看BitFieldMember模板的定义,下面是将值赋给字段的操作数=我怀疑这个问题可能出在哪里 /* used to assign a value into the field */ inline self_t& operator=(unsigned m) { uchar *arr = se
/* used to assign a value into the field */
inline self_t& operator=(unsigned m)
{
uchar *arr = selfArray();
m &= mask;
unsigned wmask = ~(mask << (7 - (lastBit & 7)));
m <<= (7 - (lastBit & 7));
uchar *p = arr + lastBit / 8;
int i = (lastBit & 7) + 1;
(*p &= wmask) |= m;
while (i < bitSize)
{
m >>= 8;
wmask >>= 8;
(*(--p) &= wmask) |= m;
i += 8;
}
return *this;
}
/*用于将值分配到字段中*/
内联self\u t运算符=(无符号m)
{
uchar*arr=selfArray();
m&=掩模;
无符号wmask=~(掩码>=8;
(*(-p)&=wmask)|=m;
i+=8;
}
归还*这个;
}
根据您的位字段定义,您需要使用一个无符号字符[5]
,并且它需要一个大端值(从下面的链接到获取此代码的位置)。您不能像从编译器错误中看到的那样将其分配给int
。一个选项是通过位移位将int
值复制到big-endianb.arr
中。类似的操作应该可以做到这一点
int result = 0x0828a0a0;
identityFieldO2M b;
b.arr[0] = (result >> 24) & 0xFF; // 0x08
b.arr[1] = (result >> 16) & 0xFF; // 0x28
b.arr[2] = (result >> 8) & 0xFF; // 0xa0
b.arr[3] = result & 0xFF; // 0xa0
IdentityField2M
未在您发布的代码中定义。显然,它不允许被分配int
。请发布您的位域定义。如果没有这些,我们将无法帮助您。抱歉!我已更新并发布了两个位域定义。我甚至在尝试传递(当前为静态)时也注意到了这一点十六进制值828a0a0这也给出了与大小调整相关的错误。例如,b={828a0a0};给出了错误:将{}内的'136880288'从'int'转换为'unsigned char'我也尝试过用几种不同的方式进行强制转换,为什么我不能静态地将其设置为十六进制值呢?我不完全确定,因为我以前这么做过。也许这与我试图设置的十六进制值是29位,而0xA0是8位有关?我想你的问题是,你没有定义“operator=”的任何匹配(操作数类型为'identityFieldO2M'和'int')谢谢Justin!但是,在检查输出时,有一个问题与我期望的不匹配:0 0 0 0 0 2 4我期望的位置:1 145 0 0 0 14 0如果我只是尝试将0x0828a0a0分离为{0x41,0x45,0x05,0x00};这将进行编译,结果是我所期望的,但我不确定如何将数组设置为这样?@SamJ因此,您的位字段定义或试图填充它的整数可能有问题。@SamJ-huh?以网络字节顺序(big-endian)int-foo=0x0828a0a0;
然后是“等效”unsigned char foo[4]={0x08,0x28,0xa0,0xa0};
那么你到底从哪里得到{0x41,0x45,0x05,0x00};
来自@SamJ如果你想identityfieldomb;
成为那个值,那么就把它设置成你想要的值。b={0x41,0x45,0x05,0x00}
就像你在上一个例子中对a所做的那样。我理解,我想我有点困惑了,因为0x08,0x28,0xa0,0xa0表示的位的数量是26,而我期望的是29位//01 0000 0101 0001 01 0 0 0010100 000//1 000 101 0001 01 0 0 0010100 000
(顶部显示预期值,底部显示结果)。是否仍要保留前导和尾随的0?如果这是一个愚蠢的问题,我表示歉意。我不能使用静态十六进制值数组,因为它最终将动态生成,并且它将包含所有填充的0,目前仅用于测试。
identityFieldO2M b;
b = result; // **error: no match for 'operator=' (operand types are 'identityFieldO2M' and 'int')**
memset(b.arr,0,sizeof(b.arr));
/* used to assign a value into the field */
inline self_t& operator=(unsigned m)
{
uchar *arr = selfArray();
m &= mask;
unsigned wmask = ~(mask << (7 - (lastBit & 7)));
m <<= (7 - (lastBit & 7));
uchar *p = arr + lastBit / 8;
int i = (lastBit & 7) + 1;
(*p &= wmask) |= m;
while (i < bitSize)
{
m >>= 8;
wmask >>= 8;
(*(--p) &= wmask) |= m;
i += 8;
}
return *this;
}
int result = 0x0828a0a0;
identityFieldO2M b;
b.arr[0] = (result >> 24) & 0xFF; // 0x08
b.arr[1] = (result >> 16) & 0xFF; // 0x28
b.arr[2] = (result >> 8) & 0xFF; // 0xa0
b.arr[3] = result & 0xFF; // 0xa0