【问题标题】:Allow use of member variable depending on preprocessor directives允许根据预处理器指令使用成员变量
【发布时间】:2020-11-09 18:37:38
【问题描述】:

考虑以下类:

class Foo 
{
public:
    #ifdef CONDITION
    int x = 0;
    #endif

    int y;

    int foo() { 
        #ifdef CONDITION
        return ++x;
        #else
        return 0;
        #endif
    }
}

int x 仅在我定义 CONDITION 时存在 - 通过 #define CONDITION 或作为预处理器定义 (-D CONDITION)

这有一个很好的优势,我无法编译它我在没有定义 CONDITION 的地方错误地使用了 x

例如: 如果我不小心写了这样的东西:

Foo f;
f.x = 10;

当我缺少-D CONDITION时,这将不允许编译

然而,当类Foo在多个项目使用的头文件中声明时,我们会遇到各种讨厌的问题,其中预处理器定义不同:
yFoo中的偏移量将不同,导致对 Foo 对象的外观有不同的解释。

问题:
有什么方法可以让任何使用Foo 的人声明x,但是当我尝试使用它而不定义CONDITION 时仍然会收到某种编译器警告/错误?

【问题讨论】:

  • ot: fooCONDITION 未定义时具有未定义的行为
  • 在不同的项目中使用 Foo 会遇到什么问题? Foo的编译不应该依赖任何header编译的顺序
  • #ifdef CONDITION int x; #else int x_Dont_Touch_Me; #endif 可能会在实践中发挥作用,尽管从技术上讲它仍然违反了 ODR。
  • 这似乎是一个 X-Y 问题(请参阅 meta.stackexchange.com/questions/66377/what-is-the-xy-problem )。大概有一些原因(即您希望实现的目标)要求仅在定义宏 CONDITION 时才使用一个类(这可能是也可能不是您实际问题的解决方案)。您如何解释您的实际问题,而不是要求您选择的解决方案?
  • @Peter 我认为你误读了这个例子。我希望能够始终使用Foo 及其成员函数foo(),我只想在CONDITION 未定义时让foo() 执行其他操作(始终返回零)。但是,由于我仅将x 用于该特定功能,所以我不想在CONDITION 未定义时犯错误。

标签: c++ c++11 macros c-preprocessor conditional-compilation


【解决方案1】:

不要让在标题中可见的定义以宏定义为条件。

如果您需要有条件地添加不同的成员,那么您必须对类的用户隐藏这些成员。这可以通过 PIMPL 模式来实现。

【讨论】:

    【解决方案2】:

    您想要的是违反 ODR。一种更简洁的方法是使 CONDITION 成为 bool 模板参数。

    但是如果你冒这个险,你可以用简化的形式来冒险,只在属性上相差x

    class Foo 
    {
        #ifndef CONDITION
        [[deprecated("Don'u use with [[condition]] defined")]]
        #endif
        int x = 0;
        int y;
    
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多