這定義是固定的,我不能改變他們(第三方LIB)名
#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智能lib和嘗試使用它:
#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)
?
不幸的是,包含在函數類宏的參數內部的宏在*替換(參數)之前被立即替換*,所以您不能傳遞宏名稱。但是,您可以通過'#'或'##'來禁止擴展。即你#定義E(M)(E,#E)'並用它來創建序列爲E(X_ERR_OK)E(X_ERR_FOO)'等等。 [Live example。](http://coliru.stacked-crooked.com/a/bf245740a9d01bd3) – dyp
http://coliru.stacked-crooked.com/a/6401e0af6b75e700 – llonesmiz
工作!感謝您對dyp和cv_and_he –