【问题标题】:define function with #define in cpp?在cpp中用#define定义函数?
【发布时间】:2014-01-11 12:40:07
【问题描述】:

如果我想多次检查某事,我对这个广告使用#define 我想使用它但它不起作用

#define CHECK_CONDITION(QString condition, start, curr) if(condition == "" ) return true; return (table.commonIn() == "team_id"? list()[start]->team() ==list()[curr]->team() :list()[start]->team() ==list()[curr]->team())

我是这样使用它的:

if(CHECK_CONDITION(table.commonIn().toStdString(), start, start-idx);) {
   findFalse = true;
}

如何在我的代码中使用这个定义/ 提前谢谢你

【问题讨论】:

  • 宏参数没有类型,删除QString
  • 为什么不使用inline 函数而不是宏?
  • @AlokSave:可能是 OP 想要生成在预处理步骤等之后易于自省的代码,或者只是想学习宏编程。
  • @LaszloPapp:由于不知道 OP 的意图,因此该建议作为评论而不是答案发布。

标签: c++ qt macros qstring qtcore


【解决方案1】:

您可以使用这个修改后的宏:

#define CHECK_CONDITION(condition, start, curr) \
    if(condition == "" || (condition == "team_id"? list()[start]->team() ==list()[curr]->team() :list()[start]->team() ==list()[curr]->team())

你在这个宏中犯的错误:

  • 为条件指定 QString

  • return 因为不会有“宏的返回值”的逻辑,但实际上会在外部函数中返回。那是因为它必须经过预处理器步骤。

  • 您不需要宏中的单独分支,因为简单的逻辑 OR(“||”)可以做到这一点。

  • 您在宏中使用了字符串 getter 中的通用表,即使您已经传递了条件变量。

  • 为了更好的可读性,我会使用反斜杠将其分成几部分。

然后您可以像这样保留其余代码:

if(CHECK_CONDITION(table.commonIn(), start, (start-idx))) {
   findFalse = true;
}

你在这里犯的错误:

  • if 条件中有一个不必要的分号,这是无效的 C++ 语法。

  • 如果不将减法放在括号中,您通常会遇到麻烦(不是这里)。

  • 如果您可以在 CHECK_CONDITION 宏调用之前为字符串和当前整数创建两个单独的变量,如下所示。

  • 您传递的是 std::string 而不是 QString。

但如果你能像这样简单地第二部分会更好:

QString myString = table.commonIn();
int curr = start - idx;

if(CHECK_CONDITION(myString, start, curr)) {
   findFalse = true;
}

免责声明:我一直在努力使您的宏及其调用者正常工作,但一般情况下尽量避免使用宏。

在某些情况下它们是有意义的,但也有替代方案,例如模板(此处不适用)或内联函数和方法(不确定是否适用于此处)。根据您的用例,您可以选择您喜欢的任何一个,但您可以从这个答案中了解如何使宏适用于您的用例。

【讨论】:

    【解决方案2】:

    C/C++ 中的#define 是一个宏定义,是一个简单的文本替换。此定义更像是一个函数,并试图将类型分配给其中一个参数。这不是合法语法,因此需要删除 QString 部分

    总体而言,尽管此代码不适合宏。参数startcurr 在扩展中都被多次使用。这意味着如果一个副作用表达式被传递给宏,它可能会被执行很多次。一个函数在这里会更合适

    【讨论】:

      【解决方案3】:

      预处理器没有类型的概念,所以当你声明一个带有类型的#define时,你不需要指定参数类型:

      #define CHECK_CONDITION(condition, start, curr) { if(condition == "" ) return true; return (table.commonIn() == "team_id"? list()[start]->team() ==list()[curr]->team() :list()[start]->team() ==list()[curr]->team())}
      

      此外,#define 会在您使用它的位置进行扩展(预处理器替换 CHECK_CONDITION 与该代码块),因此您的代码不会因为至少一个原因而编译:您将在if 条件中嵌套if,这是一个语法错误。

      改用(可能是内联的)函数:

      inline
      bool check_condition(QString condition, int start, int curr) {
          if(condition == "" ) return true;
          return (
              table.commonIn() == "team_id"?
                  list()[start]->team() == list()[curr]->team():
                  list()[start]->team() == list()[curr]->team()
          )
      }
      

      这也明确了一个可能的语法错误:我不知道你对最后两行的意思,所以我保持不变......

      我的 2cents:您应该将 C++ 中的预处理器作为最后的手段:您有模板、const 变量和内联函数。

      它留在 C++ 中的主要原因(而不是单独使用 include 关键字等)是为了保持与 C 的向后兼容性。切勿使用预处理器,除非任何其他解决方案相当复杂。

      【讨论】:

      • +1,但考虑为 startcurr 使用无符号类型,因为负值对此函数没有意义。
      • @DanielFrey 实际上我不能说,因为我不知道list 是如何定义的。它可能采用 Python 约定,接受负值作为与最后一个(而不是第一个)元素的偏移量。在那种情况下,int 会有意义...
      • 内联函数对于可自省的代码生成不太好。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2016-02-04
      • 2015-09-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多