检查 X 宏是否为空

问题描述 投票:0回答:1

我正在尝试构建一个 X 宏,它允许生成一个带有一堆有用函数(例如

.toString()
)的枚举。我得到的版本可以这样实现:

#define MAKE_ENUM \
  ENUM_NAME( LanguageId ) \
  ENUM_TYPE( unsigned int ) \
  ENUM_ENTRY( English, 0 )\
  ENUM_ENTRY( French ) \
  ENUM_ENTRY( German ) \
  ENUM_ENTRY( Italian ) \
  ENUM_ENTRY( Spanish ) \
  ENUM_ENTRY( Polish ) \
  ENUM_ENTRY( Korean, 128 ) \
  ENUM_ENTRY( ChineseTraditional, 129 ) \
  ENUM_ENTRY( ChineseSimplified, 130 ) \
  ENUM_ENTRY( Japanese, 131 )
#include "GenericToolbox.MakeEnum.h"
#undef MAKE_ENUM

X 宏

MAKE_ENUM
的部署是在标题
GenericToolbox.MakeEnum.h
下完成的。

这个版本的效果符合预期。但是我希望

ENUM_TYPE
成为可选参数,因此有时用户不会设置它,并且枚举将被定义为默认
int

为此,我需要弄清楚 MAKE_ENUM 的展开是否为空。我想出的版本是这样的:

#define TEMP_EXPAND(x) x
#define TEMP_SELECT_THIRD(_1,_2,num,...) num
#define TEMP_IS_NOT_EMPTY_IMPL(...) TEMP_EXPAND(TEMP_SELECT_THIRD(__VA_ARGS__,1,0))
#define TEMP_ARGS_DUMMY( ... ) dummy,##__VA_ARGS__
#define TEMP_IS_NOT_EMPTY( val ) TEMP_IS_NOT_EMPTY_IMPL(TEMP_ARGS_DUMMY( val ))

// [...]

#define ENUM_TYPE(type_) type_ // MAKE_ENUM will only return type_ if it exists
#if TEMP_IS_NOT_EMPTY( MAKE_ENUM ) == 1
  typedef MAKE_ENUM EnumType;
#else
  typedef int EnumType;
#endif

// [...]

问题是,

TEMP_IS_NOT_EMPTY
宏似乎只适用于 Clang,但不适用于 GCC。你知道为什么吗?还有可行的解决方法吗?

为了澄清问题,我在代码中添加了一个测试:

#define MAKE_ENUM_EMPTY
#if TEMP_IS_NOT_EMPTY( MAKE_ENUM_EMPTY ) == 1
// NOT empty
#warning "TEMP_IS_NOT_EMPTY does not work correctly for empty macro"
#else
// empty
#endif

#define MAKE_ENUM_NOT_EMPTY unsigned int
#if TEMP_IS_NOT_EMPTY( MAKE_ENUM_NOT_EMPTY ) == 1
// NOT empty
#else
// empty
#warning "TEMP_IS_NOT_EMPTY does not work correctly for NOT empty macro"
#endif

使用 GCC,我收到警告消息:

#warning "TEMP_IS_NOT_EMPTY does not work correctly for empty macro"

干杯!

c c-preprocessor
1个回答
0
投票

我不喜欢“检查是否为空”。用宏很难做到。相反,应根据参数数量重载宏。我推荐以下模式:

#define ENUM_TYPE_1(name)         ENUM_TYPE_2(name, int)
#define ENUM_TYPE_2(name, type)   typedef type name;
#define ENUM_TYPE_N(_2,_1,N,...)  ENUM_TYPE##N
#define ENUM_TYPE(...)            ENUM_TYPE_N(__VA_ARGS__,_2,_1)(__VA_ARGS_)
© www.soinside.com 2019 - 2024. All rights reserved.