【发布时间】:2011-03-21 08:41:58
【问题描述】:
我正在尝试为返回字符串长度的宏编写一些代码,并尝试使用 BOOST_PP_WHILE 来实现它。该代码源于这样一个事实,即宏参数foo表示的字符串的position指定位置处的字符可以通过#foo[position]获得。使用 MSVC 或 Intel C++ 进行编译会导致类似的语法错误;如果您能指出代码生成这些语法错误的原因以及我将如何纠正代码,将不胜感激。 我知道错误是由 PREDICATE 宏中的代码引起的,但我尝试在其中使用的任何表达式(除了 BOOST_PP_TUPLE_ELEM)都会导致编译时错误。
错误:
prog.cpp:47:1: error: pasting "BOOST_PP_BOOL_" and ""\"Hello, World!\""" does not give a valid preprocessing token
prog.cpp: In function ‘int main(int, char**)’:
prog.cpp:47: error: ‘BOOST_PP_TUPLE_ELEM_2_1’ was not declared in this scope
正如人们所预料的那样,行号并不是很有用,因为它们都指向调用宏 MACRO_STRLEN 的行。
代码
下面是我尝试实现我描述的宏的源代码列表。
#include <boost/preprocessor/arithmetic/dec.hpp>
#include <boost/preprocessor/arithmetic/inc.hpp>
#include <boost/preprocessor/comparison/equal.hpp>
#include <boost/preprocessor/control/while.hpp>
#include <boost/preprocessor/tuple/elem.hpp>
#include <cstdio>
#define TEST_STRING0 "Hello, World!"
#define MACRO_IS_NULL_IMPL(x, position) \
#x[position] == '\0'
#define MACRO_IS_NULL(x, position) \
MACRO_IS_NULL_IMPL(x, position)
#define PREDICATE_D(string, position) \
MACRO_IS_NULL(string, position)
#define PREDICATE(n, state) \
PREDICATE_D( \
BOOST_PP_TUPLE_ELEM(2, 0, state), \
BOOST_PP_TUPLE_ELEM(2, 1, state) \
)
#define OPERATION_D(string, position) \
( \
string, \
BOOST_PP_INC(position) \
)
#define OPERATION(d, state) \
OPERATION_D( \
BOOST_PP_TUPLE_ELEM(2, 0, state), \
BOOST_PP_TUPLE_ELEM(2, 1, state) \
)
#define MACRO_STRLEN_IMPL(string) \
BOOST_PP_TUPLE_ELEM( \
2, 1, BOOST_PP_WHILE(PREDICATE, OPERATION, (string, 0)) \
)
#define MACRO_STRLEN(string) \
MACRO_STRLEN_IMPL(string)
int main(int argc, char ** argv) {
printf("String length: %d.\n", MACRO_STRLEN(TEST_STRING0));
return 0;
}
【问题讨论】:
-
在 gcc 4.3.4 下编译会产生一个可能有用的额外错误 - 请参阅我的编辑。
-
奇怪的是,将两个参数粘贴在一起会导致错误...我尝试修改 PREDICATE 宏的主体,但结果相同。我无法理解为什么 BOOST_PP_TUPLE_ELEM 可以正常工作,但 MACRO_IS_NULL 不能。
-
上面的错误消息被编辑以反映 OP 编辑代码后生成的新错误消息。
-
很抱歉 - 当我查看编辑时,我想我可能最终撤消了它......
标签: c++ boost c-preprocessor metaprogramming