【问题标题】:Remove a value from an enum without changing the other values从枚举中删除一个值而不更改其他值
【发布时间】:2014-06-04 20:20:32
【问题描述】:

我有几个用作类型常量的枚举。例如:

enum item_type {
  street,
  town,
  lake,
  border,
...
}

枚举值在代码中用于指定对象类型,并作为数据文件的一部分写入磁盘。这通常效果很好,但有一个缺点:

如果不更改所有后续成员的整数值,则无法删除枚举成员(因为不再使用它)。因此,任何此类更改都会使代码与现有数据文件不兼容。

有没有什么好的技术可以避免这个问题?也许是一些预处理器技巧?

我能想到的唯一解决方案是显式设置所有整数值。虽然这可行,但对于大枚举来说很难阅读和管理。

注意:这个问题来自Navit的源代码,它使用了几个这样的“类型枚举”(虽然它们实际上隐藏在一些宏后面)。

【问题讨论】:

    标签: c enums refactoring c-preprocessor


    【解决方案1】:

    如果您想很少删除项目,您可以执行类似的操作

    enum item_type {
      street,
      town,
      //lake,
      border = town+2,
    ...
    }
    

    即仅显式地为您删除的项目之后的项目分配一个值。

    由于兼容性对您来说非常重要,因此硬着头皮明确编号所有项目会更可靠

    enum item_type {
      street = 0,
      town   = 1,
      //lake   = 2,
      border = 3,
    ...
    }
    

    【讨论】:

      【解决方案2】:

      我最终声明了一个宏 UNUSED,它扩展为 UNUSED_<linenumber>。然后可以将未使用的枚举值替换为 UNUSED。宏在它所在的每一行扩展为一个唯一标识符 使用,因为否则编译器会抱怨重复枚举 它在一个枚举中被多次使用的条目。

      如果你有很多“差距”,这有点难看。尽管如此,我还是选择了这个 simonc 解决方案的解决方案,因为它易于阅读(使常规枚举值不受视觉影响 像three=zero+2) 一样混乱,并且不需要幻数。 诚然,这只有在差距很小且相距甚远的情况下才有意义。 对于较大的差距,simonc 的解决方案看起来更好。

      完整示例:

      #include <stdio.h>
      
      #define UNUSED UNUSED_P(__LINE__)
      #define UNUSED_P(x) UNUSED_P2(x)
      #define UNUSED_P2(x) UNUSED_##x
      
      enum e {
        zero,
        UNUSED,
        UNUSED,
        three,
      };
      
      int main(void){
        printf("int value of 'three': %d\n",three);
        return 0;
      }
      

      双重替换改编自以下问题: c++ - How, exactly, does the double-stringize trick work?.

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2018-09-30
        • 1970-01-01
        • 2021-11-21
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多