我正在尝试为返回字符串长度的宏编写一些代码,并尝试使用 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
的行。
代码
下面是源代码 list ,我在其中尝试实现我描述的宏。
#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;
}
最佳答案
这个怎么样 - http://codepad.org/aT7SK1Lu 它仍然是编译时 strlen,编译速度可能会快得多。
#include <stdio.h>
#include <string.h>
#define TEST_STRING "Hello, World!"
template <int N> struct xtmp2 { typedef char (&t)[N]; };
template< class T, int N > typename xtmp2<N>::t xlen( T (&)[N] );
#define STRLEN(x) (sizeof(xlen(x))-1)
int main( void ) {
printf( "strlen(\"%s\") = %i %i\n", TEST_STRING, STRLEN(TEST_STRING), strlen(TEST_STRING) );
}
至于宏调试,可以获得预处理器输出(如 gcc -E); 取消定义大多数宏,然后一一启用它们可能也有帮助 看看会发生什么。
关于c++ - 预处理器宏代码中的语法错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5375398/