c++ - 预处理器宏代码中的语法错误

标签 c++ boost c-preprocessor metaprogramming

我正在尝试为返回字符串长度的宏编写一些代码,并尝试使用 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/

相关文章:

c++ - 在 std::strcpy 中使用 char*

c++ - 用 c++11 等价物替换 boost::thread 和 boost::mutex 是否明智?

c - C语言预处理分析

带换行符的 Fortran 预处理器宏

c++ - 使用 std::basic_istringstream 和 std::quoted 读取 std::string 末尾的带引号的字符串时设置失败位

c++ - 派生类中的 operator<< 可以在 C++ 的基类中调用另一个 operator<< 吗?

c++ - C++ 中的新功能 "synchronized" block 有什么优势?

boost - 当 Yum 版本过时时如何更新 Boost

c++ - 如何找到boost::dynamic_bitset占用的内存?

c - 如何复制 C 宏?