首页 > 解决方案 > 如何在 C++ 预处理中处理 __VA_ARGS__?

问题描述

#define INITIALIZE_INT_ARRAY(elem_type, array_name,...) \
    elem_type array_name[] = { __VA_ARGS__ }; \ 

INITIALIZE_INT_ARRAY(int, arr, 1, 2, 3, 4, 5)
// will expand to
int arr[] = {1, 2, 3, 4. 5};

现在我想支持元组,__VA_ARGS__如果它是一个元组,它将简单地获取元组的第一个元素。

INITIALIZE_INT_ARRAY(int, arr, 1, (2, hello), (3, world), (4, X), 5)
// will still expand to
int arr[] = {1, 2, 3, 4, 5}

我怎样才能改变我的INITIALIZE_INT_ARRAY

标签: c++c-preprocessorboost-preprocessor

解决方案


通常,在预处理器中遍历逗号分隔的列表需要编写O(n)样板宏。您可以自己编写或从 Boost.Preprocessor 获取它们,或者...

您可以对列表使用不同的语法:FOO(int, arr, (1)(2, hello)(3, world)(4, X)(5)).

然后宏可以这样写,没有样板:

#define FOO(type_, name_, seq_) \
    type_ name_[] = { FOO_END( FOO_LOOP_A seq_ ) }; \
    
#define FOO_END(...) FOO_END_(__VA_ARGS__)
#define FOO_END_(...) __VA_ARGS__##_END
    
#define FOO_LOOP_A(...) FOO_LOOP_BODY(__VA_ARGS__,) FOO_LOOP_B
#define FOO_LOOP_B(...) FOO_LOOP_BODY(__VA_ARGS__,) FOO_LOOP_A
#define FOO_LOOP_A_END
#define FOO_LOOP_B_END

#define FOO_LOOP_BODY(x, ...) x,

推荐阅读