我使用以下代码生成一个列表(稍后在x宏中使用)
#define LIST_OF_VARIABLES \ X(value1) \ X(value2) \ X(value3) \ X(value4) \ X(value5) \ X(value6) \ X(value7)
有没有办法生成给定大小为N的列表。结果列表包含从value0到valueN的元素?
我正在使用以下X宏
#define X(name) unsigned long long int name; LIST_OF_VARIABLES #undef X #define X(name) name =idx; LIST_OF_VARIABLES #undef X
并生成此输出
value1 =idx; value2 =idx; value3 =idx; value4 =idx; value5 =idx; value6 =idx; value7 =idx;
感谢M Oehm解决方案
//#################Q VAR GENERATION################# #define VAR(P, NNN, NN, N) P##NNN##NN##N #define NUM0(P, X, NNN, NN) X(VAR(P, NNN, NN, 0)) #define NUM1(P, X, NNN, NN) NUM0(P, X, NNN, NN) X(VAR(P, NNN, NN, 1)) #define NUM2(P, X, NNN, NN) NUM1(P, X, NNN, NN) X(VAR(P, NNN, NN, 2)) #define NUM3(P, X, NNN, NN) NUM2(P, X, NNN, NN) X(VAR(P, NNN, NN, 3)) #define NUM4(P, X, NNN, NN) NUM3(P, X, NNN, NN) X(VAR(P, NNN, NN, 4)) #define NUM5(P, X, NNN, NN) NUM4(P, X, NNN, NN) X(VAR(P, NNN, NN, 5)) #define NUM6(P, X, NNN, NN) NUM5(P, X, NNN, NN) X(VAR(P, NNN, NN, 6)) #define NUM7(P, X, NNN, NN) NUM6(P, X, NNN, NN) X(VAR(P, NNN, NN, 7)) #define NUM8(P, X, NNN, NN) NUM7(P, X, NNN, NN) X(VAR(P, NNN, NN, 8)) #define NUM9(P, X, NNN, NN) NUM8(P, X, NNN, NN) X(VAR(P, NNN, NN, 9)) #define NUM(P, X, NNN, NN, N) NUM##N(P, X, NNN, NN) #define NNUM0(P, X, NNN, N) NUM(P, X, NNN, 0, N) #define NNUM1(P, X, NNN, N) NNUM0(P, X, NNN, 9) NUM(P, X, NNN, 1, N) #define NNUM2(P, X, NNN, N) NNUM1(P, X, NNN, 9) NUM(P, X, NNN, 2, N) #define NNUM3(P, X, NNN, N) NNUM2(P, X, NNN, 9) NUM(P, X, NNN, 3, N) #define NNUM4(P, X, NNN, N) NNUM3(P, X, NNN, 9) NUM(P, X, NNN, 4, N) #define NNUM5(P, X, NNN, N) NNUM4(P, X, NNN, 9) NUM(P, X, NNN, 5, N) #define NNUM6(P, X, NNN, N) NNUM5(P, X, NNN, 9) NUM(P, X, NNN, 6, N) #define NNUM7(P, X, NNN, N) NNUM6(P, X, NNN, 9) NUM(P, X, NNN, 7, N) #define NNUM8(P, X, NNN, N) NNUM7(P, X, NNN, 9) NUM(P, X, NNN, 8, N) #define NNUM9(P, X, NNN, N) NNUM8(P, X, NNN, 9) NUM(P, X, NNN, 9, N) #define NNUM(P, X, NNN, NN, N) NNUM##NN(P, X, NNN, N) #define NNNUM0(P, X, NN, N) NNUM(P, X, 0, NN, N) #define NNNUM1(P, X, NN, N) NNNUM0(P, X, 9, NN) NNUM(P, X, 1, NN, N) #define NNNUM2(P, X, NN, N) NNNUM1(P, X, 9, NN) NNUM(P, X, 2, NN, N) #define NNNUM3(P, X, NN, N) NNNUM2(P, X, 9, NN) NNUM(P, X, 3, NN, N) #define NNNUM4(P, X, NN, N) NNNUM3(P, X, 9, NN) NNUM(P, X, 4, NN, N) #define NNNUM5(P, X, NN, N) NNNUM4(P, X, 9, NN) NNUM(P, X, 5, NN, N) #define NNNUM6(P, X, NN, N) NNNUM5(P, X, 9, NN) NNUM(P, X, 6, NN, N) #define NNNUM7(P, X, NN, N) NNNUM6(P, X, 9, NN) NNUM(P, X, 7, NN, N) #define NNNUM8(P, X, NN, N) NNNUM7(P, X, 9, NN) NNUM(P, X, 8, NN, N) #define NNNUM9(P, X, NN, N) NNNUM8(P, X, 9, NN) NNUM(P, X, 9, NN, N) #define NNNUM(P, X, NNN, NN, N) NNNUM##NNN(P, X, NN, N) //#####################Q var count#################### #define QA(X) NNNUM(qA, X, 0, 1, 6) #define QB(X) NNNUM(qB, X, 0, 1, 6) //#################################################### #define INIT(A) unsigned long long int A=EMPTY_STATE_VALUE; #define TEST(A) res[0]=A; //in code QB(INIT); QA(TEST);
答案 0 :(得分:2)
首先,我同意John Bode的回答,因为我怀疑你试图完成的事情可以通过其他一些构造更优雅地完成,而不是依赖于预处理器宏。即使你不同意“#em; macros is evil"”的常识,他们仍然是丑陋的,难以调试,而且往往容易出错且不便携。我的建议是采取不同的方法 - 最好不要依赖预处理器技巧。
如上所述,here指出,有一个Boost预处理器库可以编写预处理器循环。
以下是一个示例(来自this page on boost.org):
#include <boost/preprocessor/iteration/local.hpp>
template<int> struct sample;
#define BOOST_PP_LOCAL_MACRO(n) \
template<> struct sample<n> { \
enum { value = n }; \
}; \
/**/
#define BOOST_PP_LOCAL_LIMITS (1, 5)
#include BOOST_PP_LOCAL_ITERATE()
/* expands to...
template<> struct sample<1> { enum { value = 1 }; };
template<> struct sample<2> { enum { value = 2 }; };
template<> struct sample<3> { enum { value = 3 }; };
template<> struct sample<4> { enum { value = 4 }; };
template<> struct sample<5> { enum { value = 5 }; };
*/
答案 1 :(得分:1)
不在预处理器本身内;在宏扩展之前识别所有预处理器定义; IOW,您无法定义扩展为#define
的宏并且预处理器可以识别该定义。
您可以编写一个生成该宏的小型实用程序,您可以将其保存到头文件中。
...然而
通常情况下,当你需要一堆相同类型的变量并且仅由序数(value0
,value1
,value2
,......)区分时,你会使用数组。是否有任何特殊原因导致数组在您的情况下无用?
答案 2 :(得分:1)
哦,它可以在预处理器中完成。的种类。我不认为生成的枚举是有用的,或者方法是优雅的,但在预处理器中做事总是给出成就感。就像用针织针打开烤豆罐头一样。早上三点钟。
Anayway,这是一种允许您定义N个枚举变量的方法。您必须将N指定为单独的数百,数十和1,但是:
#define VAR(P, NNN, NN, N) P##NNN##NN##N
#define NUM0(P, X, NNN, NN) X(VAR(P, NNN, NN, 0))
#define NUM1(P, X, NNN, NN) NUM0(P, X, NNN, NN), X(VAR(P, NNN, NN, 1))
#define NUM2(P, X, NNN, NN) NUM1(P, X, NNN, NN), X(VAR(P, NNN, NN, 2))
#define NUM3(P, X, NNN, NN) NUM2(P, X, NNN, NN), X(VAR(P, NNN, NN, 3))
#define NUM4(P, X, NNN, NN) NUM3(P, X, NNN, NN), X(VAR(P, NNN, NN, 4))
#define NUM5(P, X, NNN, NN) NUM4(P, X, NNN, NN), X(VAR(P, NNN, NN, 5))
#define NUM6(P, X, NNN, NN) NUM5(P, X, NNN, NN), X(VAR(P, NNN, NN, 6))
#define NUM7(P, X, NNN, NN) NUM6(P, X, NNN, NN), X(VAR(P, NNN, NN, 7))
#define NUM8(P, X, NNN, NN) NUM7(P, X, NNN, NN), X(VAR(P, NNN, NN, 8))
#define NUM9(P, X, NNN, NN) NUM8(P, X, NNN, NN), X(VAR(P, NNN, NN, 9))
#define NUM(P, X, NNN, NN, N) NUM##N(P, X, NNN, NN)
#define NNUM0(P, X, NNN, N) NUM(P, X, NNN, 0, N)
#define NNUM1(P, X, NNN, N) NNUM0(P, X, NNN, 9), NUM(P, X, NNN, 1, N)
#define NNUM2(P, X, NNN, N) NNUM1(P, X, NNN, 9), NUM(P, X, NNN, 2, N)
#define NNUM3(P, X, NNN, N) NNUM2(P, X, NNN, 9), NUM(P, X, NNN, 3, N)
#define NNUM4(P, X, NNN, N) NNUM3(P, X, NNN, 9), NUM(P, X, NNN, 4, N)
#define NNUM5(P, X, NNN, N) NNUM4(P, X, NNN, 9), NUM(P, X, NNN, 5, N)
#define NNUM6(P, X, NNN, N) NNUM5(P, X, NNN, 9), NUM(P, X, NNN, 6, N)
#define NNUM7(P, X, NNN, N) NNUM6(P, X, NNN, 9), NUM(P, X, NNN, 7, N)
#define NNUM8(P, X, NNN, N) NNUM7(P, X, NNN, 9), NUM(P, X, NNN, 8, N)
#define NNUM9(P, X, NNN, N) NNUM8(P, X, NNN, 9), NUM(P, X, NNN, 9, N)
#define NNUM(P, X, NNN, NN, N) NNUM##NN(P, X, NNN, N)
#define NNNUM0(P, X, NN, N) NNUM(P, X, 0, NN, N)
#define NNNUM1(P, X, NN, N) NNNUM0(P, X, 9, NN), NNUM(P, X, 1, NN, N)
#define NNNUM2(P, X, NN, N) NNNUM1(P, X, 9, NN), NNUM(P, X, 2, NN, N)
#define NNNUM3(P, X, NN, N) NNNUM2(P, X, 9, NN), NNUM(P, X, 3, NN, N)
#define NNNUM4(P, X, NN, N) NNNUM3(P, X, 9, NN), NNUM(P, X, 4, NN, N)
#define NNNUM5(P, X, NN, N) NNNUM4(P, X, 9, NN), NNUM(P, X, 5, NN, N)
#define NNNUM6(P, X, NN, N) NNNUM5(P, X, 9, NN), NNUM(P, X, 6, NN, N)
#define NNNUM7(P, X, NN, N) NNNUM6(P, X, 9, NN), NNUM(P, X, 7, NN, N)
#define NNNUM8(P, X, NN, N) NNNUM7(P, X, 9, NN), NNUM(P, X, 8, NN, N)
#define NNNUM9(P, X, NN, N) NNNUM8(P, X, 9, NN), NNUM(P, X, 9, NN, N)
#define NNNUM(P, X, NNN, NN, N) NNNUM##NNN(P, X, NN, N)
然后你可以在X宏中使用它:
#define ENUM(A) A
#define STRING1(A) #A
#define STRING(A) STRING1(A)
#define LIST_OF_VARIABLES(X) NNNUM(dalmatian, X, 1, 0, 0)
enum {
LIST_OF_VARIABLES(ENUM)
};
const char *varname[] = {
LIST_OF_VARIABLES(STRING)
}
这将生成101个枚举值,称为dalmatian000
到damtaian100
加上相应的字符串实体。它们将以逗号分隔;您可以通过删除宏替换中的顶级逗号来更改此内容。
系统可以扩展超过1000个条目。
宏对于生成数字没有用,因为较低的值最终会有前导零,这使得它们成为八进制常量。但是生成十六进制常量应该很容易。
答案 3 :(得分:0)
没办法,但你可以添加一个循环(如果你知道如何生成值):
#define LIST_OF_VARIABLES(low, high) for(int i=low; i <= high; i++) { X(i); };
答案 4 :(得分:0)
有点不清楚你的意思&#34; list&#34;。我有点假设你想要某种像
这样的变量分区X(value0)
X(value1)
...
X(valuen)
但是你可以任意&#34;砍掉&#34;从结束,或可能开始,或两者的价值。答案是否定的,但您可以使用以下内容进行模拟:
<强> values_x.h 强>
#ifdef USE_VALUES_X_VALUE0
X(value0)
#endif
X(value1)
X(value2)
X(value3)
X(value4)
X(value5)
X(value6)
X(value7)
#ifdef USE_VALUES_X_TO_VALUEN
X(value8)
...
X(valuen)
#endif
因此,对于变量列表,您可以使用此文件:
#undef USE_VALUES_X_VALUE0
#undef USE_VALUES_X_TO_VALUEN
#define X(x_) unsigned long long int x_ = idx; // X-Macro code goes here
#include "values_x.h"
这就像LIST_OF_VARIABLES
。
另一种方法是使用像GNU Autogen这样的代码生成工具
为您生成不同的X-Macros标头(基本上从标头中删除#include
逻辑如上所示,并将其放入自动模板/数据文件中。)