gpt4 book ai didi

C++ 成对的可变参数宏

转载 作者:行者123 更新时间:2023-12-02 20:20:18 25 4
gpt4 key购买 nike

我知道 MAP macro可用于将宏函数应用于可变参数列表。但是如何将宏函数应用于可变参数对呢?

我想要创建的是这样的:

#define DECL_VAR(type,var)\
type _##var;
#define DECL_GETSET(type,var)\
type get_##var() const {return _##var;}\
void set_##var(type val) {_##var = val;}

#define CREATE_CLASS(C, ...)\
class C {\
private:\
MAP_PAIR(DECL_VAR, ODD_VA_ARG, EVEN_VA_ARG)\
public:\
MAP_PAIR(DECL_GETSET, ODD_VA_ARG, EVEN_VA_ARG)\
};

CREATE_CLASS(Person, const char*, name, int, age, float, height)
// or maybe
CREATE_CLASS(Person, (const char*, name), (int, age), (float, height))

最佳答案

CREATE_CLASS(Person, (const char*, name), (int, age), (float, height))

这将是更容易使用的选项,因为预处理器语法以某种方式处理平衡括号,例如(const char*, name)尽管包含逗号,但它是宏的单个参数。

因此,一个简单的解决方案是提供接受 (type, varname) 形式的参数的包装宏。 ,并将其元素传递给实际的双参数宏:

#define DECL_VAR(type,var)\
type _##var;
#define DECL_VAR_PAIR(pair)\
DECL_VAR pair
#define DECL_GETSET(type,var)\
type get_##var() const {return _##var;}\
void set_##var(type val) {_##var = val;}
#define DECL_GETSET_PAIR(pair)\
DECL_GETSET pair

#define CREATE_CLASS(C, ...)\
class C {\
private:\
MAP(DECL_VAR_PAIR, __VA_ARGS__)\
public:\
MAP(DECL_GETSET_PAIR, __VA_ARGS__)\
};

CREATE_CLASS(Person, (const char*, name), (int, age), (float, height))

例如,当扩展 MAP(DECL_VAR_PAIR, __VA_ARGS__) 时在最后CREATE_CLASS该行传递一个参数 (int, age)DECL_VAR_PAIR ,扩展的步骤包括:

DECL_VAR_PAIR((int, age))
DECL_VAR(int, age) // since DECL_VAR_PAIR(x) is just DECL_VAR then x
int _##age;
int _age;

不过,如果您想使用配对参数做很多事情,那么创建所有这些包装器宏可能会变得很麻烦。相反,我们可以添加 MAP -like 宏,期望其参数是括在括号中的列表。首先,请注意 <map.h> 中的内容,实际将宏应用于其中一个参数的步骤与主 MAP 密切相关。宏:

#define MAP0(f, x, peek, ...) f(x) MAP_NEXT(peek, MAP1)(f, peek, __VA_ARGS__)
#define MAP1(f, x, peek, ...) f(x) MAP_NEXT(peek, MAP0)(f, peek, __VA_ARGS__)
#define MAP(f, ...) EVAL(MAP1(f, __VA_ARGS__, ()()(), ()()(), ()()(), 0))

如果参数 x已经是要传递给宏的一组参数的括号 f ,我们只是希望并行版本跳过在 x 周围添加括号:

#define MAP_TUPLES0(f, x, peek, ...) f x MAP_NEXT(peek, MAP_TUPLES1)(f, peek, __VA_ARGS__)
#define MAP_TUPLES1(f, x, peek, ...) f x MAP_NEXT(peek, MAP_TUPLES0)(f, peek, __VA_ARGS__)
#define MAP_TUPLES(f, ...) EVAL(MAP_TUPLES1(f, __VA_ARGS__, ()()(), ()()(), ()()(), 0))

我称之为MAP_TUPLES而不是MAP_PAIRS因为它实际上并不限于成对。它可以将任何大小的参数列表传递给任何宏,只要宏参数的数量匹配即可。您甚至可以使用带有不同大小的参数列表的可变参数宏。

这个的用途MAP_TUPLES获取您的CREATE_CLASS ,假设您原来的 DECL_VARDECL_GETSET ,看起来像:

#define CREATE_CLASS(C, ...)\
class C {\
private:\
MAP_TUPLES(DECL_VAR, __VA_ARGS__)\
public:\
MAP_TUPLES(DECL_GETSET, __VA_ARGS__)\
};

CREATE_CLASS(Person, (const char*, name), (int, age), (float, height))

请参阅full example at coliru .

关于C++ 成对的可变参数宏,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58279658/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com