【问题标题】:how to define macro function returns void or else in C++如何在 C++ 中定义宏函数返回 void 或 else
【发布时间】:2014-08-07 00:34:12
【问题描述】:


我定义了以下两个函数宏来检查我的线程类中的退出标志。

//use this in run()
#define CHECK_EXIT  if( exitFlag_ ) {\
    //do something\
    return;\
}\

//use this in function
#define CHECK_EXIT_IN_FUNC  if( exitFlag_ ) {\
    //do something\
    return false;\
}\

我不得不单独定义它们,因为返回值不同。
我可以在一个宏中定义它吗?
我用谷歌搜索,但找不到答案。
感谢您的建议。

【问题讨论】:

  • 看起来有点像 XY 问题。我会考虑使用模板函数/类而不是预处理器宏来解决(无论如何)问题。
  • 同意——无论你想在这里做什么,你都不应该这样做。
  • 哦..你是对的。我知道 XY 问题是什么意思。也许我的问题就是其中之一..

标签: c++ macros


【解决方案1】:

您可以使用可变参数宏。如果您不想在检查后返回任何东西,则不要输入任何内容。

#define CHECK_EXIT(...) CHECK_EXIT_(_, ##__VA_ARGS__)
#define CHECK_EXIT_(...) CHECK_EXIT_X(__VA_ARGS__, _1, _0)(__VA_ARGS__)
#define CHECK_EXIT_X(_0, _1, X, ...) CHECK_EXIT ## X
#define CHECK_EXIT_0(_) do if (exit_flag_) { /*...*/ return; } while(0)
#define CHECK_EXIT_1(_, R) do if (exit_flag_) { /*...*/ return (R); } while(0)

void test_0 () {
    bool exit_flag_ = true;
    CHECK_EXIT();
}

int test_1 () {
    bool exit_flag_ = true;
    CHECK_EXIT(0);
    return 1;
}

我使用了different answer 中描述的参数计数技巧的一个非常简化的版本。我可以简化它,因为如果变量参数扩展为空,我依赖 GCC 扩展 (##__VA_ARGS__) 来删除尾随逗号。如果您使用的编译器不支持此 GCC 扩展,请使用完整版本。

【讨论】:

  • 哇.. 看起来有点困难,但我会试试这个。谢谢你的例子。
  • VA_ARGS 来自哪里?
  • @SpicyWeenie:编译器。
【解决方案2】:

我不确定您如何“在一个宏中”为不同类型的函数执行此操作,除非您选择从外部指定实际返回值。

如果您不介意这样做,那么您可以利用在 C++(但不是 C)中可以从 void 函数返回 void 表达式这一事实。例如,您可以将(void) 0 作为“void”值返回。 IE。你可以做

#define CHECK_EXIT_IN_FUNC(ret)  if( exitFlag_ ) {\
    //do something\
    return (ret);\
}

并根据函数的类型将其调用为CHECK_EXIT_IN_FUNC(false)CHECK_EXIT_IN_FUNC((void) 0)

【讨论】:

    【解决方案3】:

    返回类型的 C++11 规则创建了一个有趣的案例:

    带有非 void 类型表达式的 return 语句只能用于返回值的函数;表达式的值返回给函数的调用者。表达式的值被隐式转换为它所在函数的返回类型。

    以后

    带有void 类型表达式的return 语句只能在返回类型为cv void 的函数中使用;表达式在函数返回给它的调用者之前被计算。

    创建一个隐式转换为void 的类型似乎很自然。不幸的是,该表达式具有这种自定义类型,该类型被视为非 void 类型,因此被拒绝。

    struct does_not_work
    {
        operator void() const {}
        template<typename T> operator T() const { return T{}; }
    };
    

    我不确定是否支持改写规则以允许隐式转换为返回类型的类型,即使该返回类型为 void。

    同样,这被拒绝了:

    return {};
    

    (但void{}也是如此)

    【讨论】:

      猜你喜欢
      • 2016-08-28
      • 2021-12-18
      • 2021-12-19
      • 1970-01-01
      • 2017-07-13
      • 2011-03-26
      • 2018-02-26
      • 2013-12-03
      • 2017-02-23
      相关资源
      最近更新 更多