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

name of defined constants in boost.preprocessor

本文关键字:常量 定义 preprocessor boost      更新时间:2023-10-16

这个定义是修复的,我不能改变它们(第三方库)

#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)

我怀疑这是可以接受的,但无论如何我都会添加它,以防它有所帮助。使用这种方法,您需要更改调用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;
}