[英]Flip the order of X and Y in MACRO(X)(Y)
我有一個基於C ++宏的DSL,它定義了一個像這樣的宏:
#define RETURNS(...) \
enable_if_t<__VA_ARGS__ WHEN
#define WHEN(...) \
, EAT_ ## __VA_ARGS__ >
#define EAT_requires
這是用於:
template<class T>
auto some_function(T t) ->
RETURNS(int)
(requires SomeConcept<T>)
其中擴展為:
template<class T>
auto some_function(T t) ->
enable_if_t<int, SomeConcept<T>>
(當啟用C ++ 20概念時,這會擴展為實際的requires
子句。)
我希望翻轉參數的順序。 也就是說,我希望它產生這個:
template<class T>
auto some_function(T t) ->
enable_if_t<SomeConcept<T>, int>
我認為這是不可能的。 一些聰明的PP黑客可以證明我錯了嗎?
如果省略一個開放的paren是可以容忍的,你可以這樣做:
#define UNWRAP(...) __VA_ARGS__
#define RETURNS(...) \
WHEN ((__VA_ARGS__),
#define WHEN(x, ...) \
enable_if_t<EAT_ ## __VA_ARGS__, UNWRAP x>
#define EAT_requires
template<class T>
auto some_function(T t) ->
RETURNS(pair<int, int>)
requires SomeConcept<T, int>)
輸入:
template<class T>
auto some_function(T t) ->
RETURNS(pair<int, int>)
requires SomeConcept<T, int>)
輸出:
template<class T>
auto some_function(T t) ->
enable_if_t< SomeConcept<T, int>, pair<int, int> >
你為什么不用像
template<class T,bool B>
using reverse_enable_if_t=enable_if_t<B,T>;
另一個看法是:
#define RETURNS(...) REVERSE_ENABLE_IF_T((__VA_ARGS__))
#define REQUIRES ),(
#define UNWRAP(...) __VA_ARGS__
#define REVERSE_ENABLE_IF_T(PT,PB) enable_if_t<UNWRAP PB,UNWRAP PT>
它允許以下parens平衡語法:
template<class T>
auto some_function(T t) ->
RETURNS(pair<int, int> REQUIRES SomeConcept<T, int>);
這是一個不需要不匹配的括號的解決方案,但需要在整個事物周圍添加一個EVAL宏:
#define EVAL( ... ) EVAL1( __VA_ARGS__ )
#define EVAL1( ... ) EVAL0( EVAL0( EVAL0( __VA_ARGS__ ) ) )
#define EVAL0( ... ) __VA_ARGS__
#define EMPTY()
#define DEFER( ... ) __VA_ARGS__ EMPTY()
#define EAT_requires
#define SWAP( X, Y ) enable_if_t<EAT_##Y, X>
#define RETURNS( X ) DEFER( SWAP )( X, ADD_PAREN
#define ADD_PAREN( Y ) Y )
然后,您可以編寫以下內容:
EVAL(
template<class T>
auto some_function(T t) ->
RETURNS(int)
(requires SomeConcept<T>)
)
它產生:
template<class T>
auto some_function( T t ) ->
enable_if_t<SomeConcept<T>, int>
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.