在 MSVC 中处理宏中的额外括号
Posted
技术标签:
【中文标题】在 MSVC 中处理宏中的额外括号【英文标题】:Dealing with extra parentheses in macros in MSVC 【发布时间】:2018-04-19 19:28:15 【问题描述】:在某些情况下,您需要 (a) 有一个宏,该宏 (b) 在 (c) 语言不允许括号的情况下将其参数之一括起来。
简单示例:
#define MAKE_STRUCT(name, base) struct name : base
struct X ;
MAKE_STRUCT(Y, X); // ok
MAKE_STRUCT(Z, (X)); // error
这是一个错误,因为我们需要一个类型名称并且我们得到(
。 ecatmur 利用语言的其他部分确实允许额外的括号集这一事实,为此提供了一个巧妙的解决方法:
template<typename T> struct argument_type;
template<typename T, typename U> struct argument_type<T(U)> typedef U type; ;
#define MAKE_STRUCT(name, base) struct name : argument_type<void(base)>::type
struct X ;
MAKE_STRUCT(Y, X); // ok
MAKE_STRUCT(Z, (X)); // ok
这可以在 gcc 和 clang 上编译,但不能在 MSVC 上编译。是否存在允许使用括号的特定于 MSVC 的技巧或适用于所有三个编译器的不同技巧?
这个可能带括号的类型通过几个宏传递 - 所以我不确定其他答案是否适用(这里的上下文是尝试使用 Catch2 的 TEST_CASE_METHOD()
将多个模板参数传递给夹具)。
【问题讨论】:
@VTT 不。没有这样的运气。 【参考方案1】:因此,我想到了以下纯预处理器解决方案,该解决方案仅在括号存在时才去除括号。似乎可以在 vc++、g++ 和 clang++ 中工作,并且可能可以修改以处理多个级别的括号。
#define MAKE_STRUCT(name, base) struct name: EXPAND1(DEF base)
#define EXPAND1(param) EXPAND2(param)
#define EXPAND2(param) NO## param
#define DEF(param) DEF param
#define NODEF
struct X ;
MAKE_STRUCT(Y, X); // ok
MAKE_STRUCT(Z, (X)); // ok
online compiler
【讨论】:
在我的情况下,X
中确实有一个逗号,但将DEF
和EXPAND2
改为...
是一个微不足道的改变。太好了,谢谢。预处理器对我来说基本上还是很神奇的。【参考方案2】:
不是很好的解决方案,但如果可以修改有问题的结构,并且只支持一级括号,这似乎可行:
struct tag ;
#define MAKE_STRUCT(name, base) struct name : \
decltype(base(tag)) ;
struct X
X(tag );
X() = default;
;
MAKE_STRUCT(Y, X); // ok
MAKE_STRUCT(Z, (X)); // ok
【讨论】:
不幸的是,没有。但我很着迷这是有效的,而base()
却没有?以上是关于在 MSVC 中处理宏中的额外括号的主要内容,如果未能解决你的问题,请参考以下文章