构建一组对象并将它们放入元组中

时间:2015-01-13 17:41:07

标签: c++ macros tuples c-preprocessor

基本上我需要做的是这样的事情:

int a = 1;
float q = 3.3;
char g = 'e';

// ... other useful variables...

auto my_tuple = std::make_tuple(a, q, g/*, ... and so on... */);

现在,我总是害怕忘记将我的变量添加到my_tuple,每次添加新变量时添加变量并将变量添加到元组都很无聊。

所以我想知道是否有办法用宏做这样的事情。作为一个例子我可以做

#define DECLARE_VARIABLE(t, n, v) t n = v;

但这只会创建变量。有没有办法添加像

这样的东西
#define END_OF_VARIABLES .....

这样我就可以写

DECLARE_VARIABLE(int, a, 1)
DECLARE_VARIABLE(float, q, 3.3)
DECLARE_VARIABLE(char, g, 'e')
// ...

END_OF_VARIABLES

my_tuple会自动构建吗? 我也可以接受导致相同结果的类似解决方案,例如

DECLARE_ALL_VARIABLES_AND_BUILD_MY_TUPLE(int, a, 1, float, q, 3.3, char, g, 'e'/*...*/)

也可以。

是否可以做这样的事情?

1 个答案:

答案 0 :(得分:2)

我不认为这是解决问题的最好方法。底部有一个直接的解决方案,但在我们开始之前:我会考虑的事情:

  • 使用struct / class而不是tuple
  • 使用枚举使元组元素更易于访问
  • 使用将元组元素映射到有意义的getter函数的访问器类
  • 使用有意义的命名访问者函数,接受元组作为参数

如果您仍然确定要使用预处理器执行此操作:存在Boost.Preprocessor,并且随之而来,各种或多或少疯狂的预处理器技巧都成为可能。你可以做这样的事情:

#include <boost/preprocessor.hpp>

#define DECLARE_VARIABLE(r, data, elem) BOOST_PP_TUPLE_ELEM(3, 0, elem) BOOST_PP_TUPLE_ELEM(3, 1, elem) = BOOST_PP_TUPLE_ELEM(3, 2, elem);
#define ISOLATE_VARNAME(r, data, elem) (BOOST_PP_TUPLE_ELEM(3, 1, elem))

#define VARSEQ ((int, x, 2)) ((char, g, 'a')) ((double, y, 2.0))

BOOST_PP_SEQ_FOR_EACH(DECLARE_VARIABLE, _, VARSEQ)
auto mytuple = std::make_tuple(BOOST_PP_SEQ_ENUM(BOOST_PP_SEQ_FOR_EACH(ISOLATE_VARNAME, _, VARSEQ)));

这里VARSEQ是Boost.PP所谓的元组所谓的序列。序列是

的形式
(a)(b)(c)

元组是一种形式

(a, b, c)

&#34;功能&#34;我用的是

  • BOOST_PP_TUPLE_ELEM从元组中提取元素
  • BOOST_PP_SEQ_FOR_EACH将宏应用于序列的所有元素
  • BOOST_PP_SEQ_ENUM列出序列中包含逗号的所有元素

有关详细信息,请参阅上述文档的链接。

顺便提一下,如果你完全疯了,那么这个实现是开源的,也是一个有趣的读物;他们真的不得不处理预处理器给他们的东西。循环使用长级数的编号宏进行模拟,其中一个扩展到它应该做的事情,并且级联中的下一个宏继续循环,以及BOOST_PP_ITERATE一个文件所在的#include内容{{1}}多次使用不同的流量控制宏定义是我从未见过的生产代码中最常用的技巧之一。