【问题标题】:C++ preprocessor add word if conditionC++ 预处理器添加单词 if 条件
【发布时间】:2014-03-23 01:53:51
【问题描述】:

我正在编写一个使用预处理器元编程 Boost.Preprocessor 的库。一个宏看起来像这样:

#define MY_MACRO(my_type) return some_function<my_type>()

现在,问题是如果my_typevoid,我需要删除return。我检查了 Boost.Preprocessor,但没有看到任何可以帮助我的东西。我该如何做到这一点?比如:

#define MY_MACRO(my_type) BOOST_PP_IF(\
      TYPE_EQUALS(my_type,void),return,BOOST_PP_EMPTY()) some_function<my_type>()

【问题讨论】:

  • 预处理器对类型知之甚少;这将很难甚至不可能。你在处理 C++ 模板吗?如果是这样,您应该将问题重新标记为 C++,并从主题中删除 C。
  • @JonathanLeffler:我只想检查给定的标识符是否等于void
  • 是的;我明白。这会很困难。我相信,预处理器是图灵完备的,所以它可能可以完成,但是“可以完成”和“可以明智地完成”是两个非常不同的事情。
  • 为什么不使用&lt;type_traits&gt;中提供的工具?
  • 你可能不需要做任何事情。如果函数没有返回任何内容(即返回类型为void),那么您可以返回void 类型的表达式。

标签: c++ boost-preprocessor


【解决方案1】:

不幸的是,boost 预处理器没有简单的方法来比较两个标记。当然,对于您的情况,您可能只需要使用一些简单的检测。这应该适用于 C99 预处理器:

#define CHECK_N(x, n, ...) n
#define CHECK(...) CHECK_N(__VA_ARGS__, 0,)
#define PROBE(x) x, 1,

#define IS_VOID(x) CHECK(BOOST_PP_CAT(IS_VOID_, x))
#define IS_VOID_void PROBE(~)

但是,这不适用于括号、可变数据(例如其中带有逗号的类型)或指针。因此,以下是有效和无效的:

IS_VOID(int) // 0
IS_VOID(void) // 1
IS_VOID((void)) // Compile error
IS_VOID(std::map<int, int>) // Compile error
IS_VOID(void*) // Returns 1, but should return 0

您可以尝试解决所有这些情况,或者您可以使用更通用的比较宏(例如here):

#define IS_PAREN(x) CHECK(IS_PAREN_PROBE x)
#define IS_PAREN_PROBE(...) PROBE(~)

#define IS_COMPARABLE(x) IS_PAREN( CAT(COMPARE_, x) (()) )

#define NOT_EQUAL(x, y) \
IIF(BITAND(IS_COMPARABLE(x))(IS_COMPARABLE(y)) ) \
( \
   PRIMITIVE_COMPARE, \
   1 EAT \
))(x, y)

#define EQUAL(x, y) COMPL(NOT_EQUAL(x, y))

#define COMPARE_void(x) x
#define IS_VOID(x) EQUAL(x, void)

可以更新它以使用 boost 预处理器组件。这应该适用于更多情况,但仍然不适用于括号(这可能不是问题)。

最后,这只是文本层面的比较,所以如果用户有typedef void,会错误返回false:

typedef void my_void;
IS_VOID(my_void) // Returns 0

如果您使用检测技术,您可以允许用户将其扩展为用户定义的空隙,如下所示:

#define IS_VOID(x) CHECK(BOOST_PP_CAT(IS_VOID_, x))
#define IS_VOID_void PROBE(~)
// User-defined void
#define IS_VOID_my_void PROBE(~)

【讨论】:

  • 天才!我从来没有想过这个!我不需要担心括号或逗号。谢谢!
猜你喜欢
  • 1970-01-01
  • 2021-06-02
  • 1970-01-01
  • 1970-01-01
  • 2018-06-18
  • 1970-01-01
  • 1970-01-01
  • 2010-09-22
  • 2017-04-19
相关资源
最近更新 更多