将字符串字面值和整数常量组合

4

如果给你一个编译时的常量整数(一个对象,而不是宏),你可以在编译时使用预处理器将它与字符串字面值组合起来吗?

例如,我可以通过将字符串字面值放在一起来连接它们:

bool do_stuff(std::string s);
//...
do_stuff("This error code is ridiculously long so I am going to split it onto "
         "two lines!");

太棒了!但是如果我加入整数常量会怎样呢:
const unsigned int BAD_EOF = 1;
const unsigned int BAD_FORMAT = 2;
const unsigned int FILE_END = 3;

有没有可能使用预处理器将此内容与字符串文字拼接起来?

do_stuff("My error code is #" BAD_EOF "! I encountered an unexpected EOF!\n"
         "This error code is ridiculously long so I am going to split it onto "
         "three lines!");

如果不可能的话,我能把常量字符串和字符串字面量混合使用吗?也就是说,如果我的错误代码是字符串而不是无符号整数?
如果两者都不可能,那么拼接这些字符串字面量和数值型错误代码的最简洁、最干净的方法是什么?
2个回答

10

如果BAD_EOF是一个宏,你可以将其字符串化

#define STRINGIZE_DETAIL_(v) #v
#define STRINGIZE(v) STRINGIZE_DETAIL_(v)

"My error code is #" STRINGIZE(BAD_EOF) "!"

但实际上并不是这样(这通常是一件好事),所以您需要格式化字符串

stringf("My error code is #%d!", BAD_EOF)

stringstream ss; ss << "My error code is #" << BAD_EOF << "!";
ss.str()

如果这对你来说很重要(一开始肯定不是),为每个常量使用单独的专用字符串:
unsigned const BAD_EOF = 1;
#define BAD_EOF_STR "1"

这具有宏的所有缺点,再加上更多维护成本,只为了获得一点性能提升,对于大多数应用程序可能 并不重要。然而,如果您决定进行这种权衡,必须使用宏,因为预处理器无法访问 ,即使它们是常量。


啊,是的。那个双重宏很重要。这是我在例子中忘记的东西。干得好。 - JoshD

0

以下代码有什么问题:

do_stuff(my_int_1,
     my_int_2,
     "My error code is #1 ! I encountered an unexpected EOF!\n"
     "This error code is ridiculously long so I am going to split it onto "
     "three lines!");

如果你想要将错误代码抽象化,那么你可以这样做:

#define BAD_EOF "1"

然后您可以像字符串文字一样使用BAD_EOF。


2
嗯,如果那个 #define 被用作整型,这可能会破坏很多代码。 - Chubsdad

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接