【问题标题】:How do I do bit operations on a struct?如何对结构进行位操作?
【发布时间】:2012-07-17 08:47:18
【问题描述】:

我有一个位域结构,我想使用掩码对其执行按位运算。 我想知道最简单、最有效的方法。 我尝试使用我的转换运算符(这似乎是对两个结构执行 & 操作的一种低效方式),但我收到错误 C2440: 'type cast' : cannot convert from 'const test::dtType' to 'char'。没有可以执行此转换的用户定义转换运算符,或者无法调用该运算符

class test
{
   public:
    test() : startTime(0), endTime(5,23) {}
    ~test();

    struct dtType {
        // inline constructors with initialisation lists
        dtType() {dtType(0);}
        dtType(byte z) {dtType(z,z);}
        dtType(byte n,byte h) : mins(n), hrs(h){}

        // inline overloaded operator functions
        operator char() {return mins + hrs<<3;}; // allow casting the struct as a char

        // All I want to do is return (this & hrsMask == date & hrsMask)
        // I know that in this trivial case I can do return (hrs == date.hrs) but I have simplified it for this example.
        bool operator== (dtType date){return (char(this) & char(hrsMask)) == (char(date) & char(hrsMask));};

        // data members
        unsigned mins: 3; // 10's of mins
        unsigned hrs: 5; // 8 bits
    };
    const static dtType hrsMask; // initialised outside the declaraion, since a static is not associated with an individual object.
    dtType startTime; // initialised by test() in its initialisation list
    dtType endTime; // initialised by test() in its initialisation list
};

// Typically in a source file, but can be in the header.
const test::dtType hrsMask(0,31);

我尝试过使用 void 指针进行按位运算。它可以编译,但我还没有测试过。

bool test::dtType::operator== (dtType date){
    const void * longThisDT = this;
    const void * longThatDT = & date;
    const void * longMaskDT = & hrsMask;
    return (*((long *)longThisDT) &  *((long *)longMaskDT) == *((long *)longThatDT) &  *((long *)longMaskDT));
};

这是否尽可能高效?它涉及三个额外的指针,而我真正需要的只是转换为 long。

【问题讨论】:

  • 我通常使用联合和/或位域来处理这类东西。
  • 我从一个联合开始,但你不能拥有一个包含具有非平凡构造函数的结构的联合。
  • 而包含位域的联合并没有多大意义。
  • @James:为什么不用位域的联合呢?我使用位域进行操作,并使用联合中的 long 将位域存储到 EEPROM。
  • @StephenD 如果它完全是本地的,它会工作,但为什么不将结构与位域本身一起存储。与位域联合的通常使用是匹配一些外部布局,然而,这不起作用,因为位域的布局没有指定,并且可以在不同的实现之间变化。

标签: c++ struct bit-manipulation conversion-operator


【解决方案1】:

首先花点时间准备 WORKING 示例,您的示例有很多错误:
- 没有定义~测试
- const test::dtType hrsMask(0,31); 不正确,应该是:const test::dtType test:hrsMask(0,31);

除此之外:
- 您应该将 operator char() { 更改为 operator char() const { - 这正是编译器抱怨的原因:)
- 不应该有 byte mins: 3 而不是 unsigned mins: 3 这真的意味着'unsigned int',所以无论如何都使用4个字节

【讨论】:

  • unsigned mins : 3; 表示 3 位,位于较大元素中的某个位置。 (较大元素的位置和类型由实现定义。)
  • 是的,但是我们收到的样本只有 'unsigned' 有 2 个元素,所以这意味着编译器的 'unsigned int',这就是我的意思
  • 我发布的示例在没有 operator= 行的情况下编译得很好。这是一个 8 位微控制器,我只展示了整个位域的一部分。根据我的 c++ 书,我只需要在位域中定义无符号位即可。谢谢。使运算符 char() const 确实有效。但是有没有更有效的方式对位域进行按位运算?
  • @zodi 我不确定你在说什么。我看到的代码有unsigned mins : 3;,它定义了一个三位元素。
  • @James:是的,3 位,但是取自什么数据类型?在这种情况下,'unsigned int' 仍然是 4 个字节,32 位长(在大多数情况下)。正如 StephenD 所指出的,这并不是什么大问题——这只是他代码的一部分。
【解决方案2】:

它在 this 被间接并移除 const 时起作用:

bool operator== (dtType date) {
    return (char(*this) & char(hrsMask)) == (char(date) & char(hrsMask));};

/* ... */

static dtType hrsMask;

/* ... */

 test::dtType test::hrsMask(0,31);

【讨论】:

  • James 和 Zodi 正在争论位域类型而忽略了我的问题。您知道在位域上进行按位运算的更有效方法吗?由于我有非平凡的构造函数,我不能使用联合。空指针呢?我以前从来没有用过。我只需要让编译器让我将位域视为长。有什么想法吗?
猜你喜欢
  • 1970-01-01
  • 2010-11-14
  • 1970-01-01
  • 2014-02-15
  • 1970-01-01
  • 2014-03-25
  • 2010-12-21
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多