【问题标题】:Remove dependancy constants from enum definition从枚举定义中删除依赖常量
【发布时间】:2010-02-24 14:33:21
【问题描述】:

我正在尝试通过使用不透明结构和前向声明从我的项目中安全地删除依赖项,但像大多数人一样,我仍然停留在我的枚举上。

我试图从头文件中删除的头文件依赖项定义了我想将枚举值设置为的常量。像这样的

// depends header
#define DEP_TYPE_ONE   1
#define DEP_TYPE_TWO   2
#define DEP_TYPE_THREE 3

// My header
enum TYPES
{
    T_ONE     = DEP_TYPE_ONE,
    T_TWO     = DEP_TYPE_TWO,
    T_THREE   = DEP_TYPE_THREE
}

我正在尝试找出一种不必在我的标题中包含依赖标题的方法。

答案很可能只是“你不能那样做”,但我只是想问一下,因为一个解决方案会让我的生活变得无限轻松。

【问题讨论】:

    标签: c++ dependencies pimpl-idiom


    【解决方案1】:

    如何删除依赖头的包含,硬编码值,并注释依赖:

    // my_header.h
    
    // NOTE: Enumerands must be in sync with symbols defined in depends.h
    enum TYPES
    {
        T_ONE     = 1, // DEP_TYPE_ONE
        T_TWO     = 2, // DEP_TYPE_TWO
        T_THREE   = 3  // DEP_TYPE_THREE
    };
    

    为了减轻对值不同步的担忧,您可以使用另一个包含一个或多个编译时断言的头文件或源文件(您的类或 API 的用户无法获得的文件):

    // Some non-distributed file
    
    #include <depends.h>
    #include "my_header.h"
    
    // Compile-time assertion macro
    #define compile_time_assert(cond, msg) \
        typedef char msg[(cond) ? 1 : -1]
    
    // Check assumptions at compile time...
    compile_time_assert(T_ONE==DEP_TYPE_ONE, ValueOutOfSync1);
    compile_time_assert(T_TWO==DEP_TYPE_TWO, ValueOutOfSync2);
        .
        .
        .
    

    如果值不同步,这会给你一个编译时错误。

    有关 compile_time_assert 宏的更多信息,请参阅:http://www.embedded.com/columns/programmingpointers/164900888?_requestid=379501

    【讨论】:

    • 编译时断言!真是个好主意!
    【解决方案2】:

    这不是你想要的,但它是在你的头文件中不包含依赖头文件的唯一方法:

    enum TYPES 
    { 
        T_ONE     = 1, 
        T_TWO     = 2, 
        T_THREE   = 3 
    } 
    

    【讨论】:

    • tbh 我几乎可以保证这些价值观永远不会改变,但在写这些时我会感到非常不安全
    【解决方案3】:

    不是一个完美的答案,但您是否考虑过匿名枚举?我曾经在使用一个图表库时遇到过类似的问题,该库在具有很多内部依赖性的标头中定义了很多常量。这影响了我们的编译时间。所以,我只是将整个#define's 模拟到标题中匿名命名空间中的匿名枚举中!类似的东西:-

    namespace {
      enum {
        DEP_TYPE_ONE = 1,
        DEP_TYPE_TWO,
        // ....
        DEP_TYPE_LAST
      };
    }
    

    使用这种方法,您不必重构大量直接使用这些命名常量的代码。但是,一旦标头定义了新常量,就立即更新枚举是维护的噩梦

    我猜你的情况值得一试。

    HTH,

    【讨论】:

    • 这是一个有趣的想法。将依赖项标头添加到我的项目标头可分发中实际上只是一步之遥,但这样做的好处是:p
    【解决方案4】:

    你是对的,你不能。您在这里处理的是预处理器而不是编译器(与前向声明一样)。

    如果您的编译器支持"forced include" 选项,则可能会“伪造”它,但依赖关系仍然存在,您仍然需要构建文件。

    【讨论】:

      猜你喜欢
      • 2021-04-08
      • 1970-01-01
      • 2014-10-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多