boost.preprocessor中已定义常量的名称

时间:2014-02-26 15:04:19

标签: c++ boost

这个定义是修复,我无法改变它们(第三方库)

#define X_ERR_OK (0)
#define X_ERR_FOO (816)
#define X_ERR_OTHER (842)
// .. and more

有一个小函数,它返回错误代码的名称(我的代码,我可以更改它)

#define X_ERR_CASE( e ) case e: return #e
const char* err_name( int err ) {
    switch( err ) {
    X_ERR_CASE( X_ERR_OK );
    X_ERR_CASE( X_ERR_FOO );
    X_ERR_CASE( X_ERR_OTHER );
    }
    return "<unknown>";
}
这是有效的。现在我发现boost.preprocessor是一个智能库并尝试使用它:

#define XX_ERR_CASE( r, _, e ) case e: return BOOST_PP_STRINGIZE(e);
#define XX_ERRORS( seq ) \
    const char* err_name2( int err ) { \
        switch( err ) { \
        BOOST_PP_SEQ_FOR_EACH( XX_ERR_CASE, _, seq ) \
        } \
        return "<unknown>";  }

XX_ERRORS(
    (X_ERR_OK)
    (X_ERR_FOO)
    (X_ERR_OTHER)
)

但这不起作用,因为输出不是定义的名称而是数字。例如,我希望:X_ERR_FOO,但我得到(816)

如果我将XX_ERR_CASE更改为

#define XX_ERR_CASE( r, _, e ) case e: return #e;

我得到BOOST_PP_SEQ_HEAD(((816)) ((842)) (nil))

我如何X_ERR_FOO致电err_name(816)

1 个答案:

答案 0 :(得分:1)

我怀疑这是可以接受的,但无论如何我会添加它以防万一。使用此方法,您需要更改调用XX_ERRORS的方式,其参数需要删除其X_前缀。

#include <iostream>
#include <boost/preprocessor.hpp>

#define X_ERR_OK (0)
#define X_ERR_FOO (816)
#define X_ERR_OTHER (842)


#define XX_ERR_CASE( r, _, e ) case BOOST_PP_CAT(X_,e): return "X_" BOOST_PP_STRINGIZE(e);
#define XX_ERRORS( seq ) \
    const char* err_name2( int err ) { \
        switch( err ) { \
        BOOST_PP_SEQ_FOR_EACH( XX_ERR_CASE, _, seq ) \
        } \
        return "<unknown>";  }

XX_ERRORS(
    (ERR_OK)
    (ERR_FOO)
    (ERR_OTHER)
)

int main()
{
    std::cout << err_name2(816) << std::endl;
}