根据参数数量生成多个宏调用 [英] Generate multiple macro calls according to the number of arguments
问题描述
我试图以重复的方式多次调用此函数.
I'm trying to call this function several times in a repeditive fashion.
template<class T>
void METADATA_METHODS_IMPL(std::string& metadata, const T &value, const std::string &key)
{
metadata += boost::format("%1%:%2%") % key % value();
}
我写了以下宏:
#define METADATA_METHODS_IMPL_1(md, v1)\
METADATA_METHODS_IMPL(md, v1, #v1);
#define METADATA_METHODS_IMPL_2(md, v1, v2)\
METADATA_METHODS_IMPL_1(md, v1)\
METADATA_METHODS_IMPL_1(md, v2)
#define METADATA_METHODS_IMPL_3(md, v1, v2, v3)\
METADATA_METHODS_IMPL_2(md, v1, v2)\
METADATA_METHODS_IMPL_1(md, v3)
以此类推...
我需要调用METADATA_METHODS_IMPL_N
,其中N
是__VA_ARGS__
中的多个参数
I need to call METADATA_METHODS_IMPL_N
where N
is a number of arguments in __VA_ARGS__
#define METADATA_METHODS(...)\
std::string METADATA_METHODS_IMPL_FUNC()\
{\
std::string metadata;\
BOOST_PP_OVERLOAD(METADATA_METHODS_IMPL_,__VA_ARGS__)(metadata, __VA_ARGS__)\
return metadata;\
}
上面的代码(带有BOOST_PP_OVERLOAD
)给了我不合适的结果:
The code above (with BOOST_PP_OVERLOAD
) gives me unsuitable result:
class X
{
std::string F1();
std::string F2();
std::string F3();
METADATA_METHODS(F1, F2, F3);
};
这导致
std::string METADATA_METHODS_IMPL_FUNC()
{
std::string metadata;
METADATA_METHODS_IMPL(metadata, F1, F2, F3, "F1", "F2", "F3");
METADATA_METHODS_IMPL(metadata, , "");
METADATA_METHODS_IMPL(metadata, , "");
return metadata;
};
我想要这样的东西:
std::string METADATA_METHODS_IMPL_FUNC()
{
std::string metadata;
METADATA_METHODS_IMPL(metadata, F1, "F1");
METADATA_METHODS_IMPL(metadata, F2, "F2");
METADATA_METHODS_IMPL(metadata, F3, "F3");
return metadata;
};
- 有人知道如何达到预期的结果吗?
- 我可以使用
Boost.preprocessor
库为使用METADATA_METHODS_IMPL_1
的某些K in [1 .. 10]
自动生成METADATA_METHODS_IMPL_K
- Does anyone know how to achieve the desired result?
- Can I use
Boost.preprocessor
library to automagically generateMETADATA_METHODS_IMPL_K
for someK in [1 .. 10]
usingMETADATA_METHODS_IMPL_1
推荐答案
使用这些宏,我们可以使预处理器保持重新扫描并允许递归宏.
Using these macros we can cause the preprocessor to keep rescanning and allow for recursive macros.
#define EVAL(...) EVAL3(EVAL3(EVAL3(__VA_ARGS__)))
#define EVAL3(...) EVAL2(EVAL2(EVAL2(__VA_ARGS__)))
#define EVAL2(...) EVAL1(EVAL1(EVAL1(__VA_ARGS__)))
#define EVAL1(...) EVAL0(EVAL0(EVAL0(__VA_ARGS__)))
#define EVAL0(...) __VA_ARGS__
我们可以定义一些辅助函数来构建概念.
We can define some helper functions to build up concepts.
#define CAT(a, ...) PRIMITIVE_CAT(a,__VA_ARGS__)
#define PRIMITIVE_CAT(a, ...) a ## __VA_ARGS__
#define EMPTY()
#define EAT(...)
#define IDENT(...) __VA_ARGS__
#define DEFER(id) id EMPTY()
#define OBSTRUCT(...) __VA_ARGS__ DEFER(EMPTY)()
#define I_TRUE(t,f) t
#define I_FALSE(t,f) f
#define I_IS_DONE(a,b,...) b
#define TRUE_DONE() ~, I_TRUE
#define IS_DONE(b) OBSTRUCT(I_IS_DONE)(CAT(TRUE_,b)(),I_FALSE)
并构建此宏映射函数,该函数将第一个参数传递给每个宏.
And build this Macro Mapping function that carries the first parameter to each.
#define MM() MM_CALL
#define MM_NEXT(Macro,md,a,...) \
IS_DONE(a)( \
EAT \
, \
OBSTRUCT(MM)() \
) \
(Macro,md,a,__VA_ARGS__)
#define MM_CALL(Macro,md,a,...) \
Macro(md,a) \
MM_NEXT(Macro,md,__VA_ARGS__)
#define MacroMap(Macro,md,...) EVAL(MM_CALL(Macro,md,__VA_ARGS__,DONE))
定义实现相关功能后
#define METADATA_METHODS_IMPL_MACRO(md,a) \
METADATA_METHODS_IMPL(md, a, #a);
#define METADATA_METHODS(md,...) \
MacroMap(METADATA_METHODS_IMPL_MACRO,md,__VA_ARGS__) \
return md
此:
METADATA_METHODS(metadata, F1, F2, F3);
结果(添加一些格式后):
Results in this (after adding some formatting):
METADATA_METHODS_IMPL(metadata, F1, "F1");
METADATA_METHODS_IMPL(metadata, F2, "F2");
METADATA_METHODS_IMPL(metadata, F3, "F3");
return metadata;
这篇关于根据参数数量生成多个宏调用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!