【问题标题】:Stringifying a block of text in C++11在 C++11 中对文本块进行字符串化
【发布时间】:2014-03-26 16:02:46
【问题描述】:

在我正在处理的代码中有宏

#define STRINGIFY(...) #__VA_ARGS__

已定义。

这确实有它忽略换行符的缺点。

因此,我想定义一个使用新的R"literal( ... )literal" 格式的宏。

鉴于宏形式已经存在,我想保留STRINGIFY宏的使用

但是考虑到涉及引号,您将如何定义STRINGIFY 以使用新的字符串文字格式?

还有在STRINGIFY宏中保留#ifdefs吗?

编辑我想要一个定义,它将在 C++11 中转换为 R"literal(...)literal"

编辑2 我能得到的最接近的是:

#define STRINGIFY1(a) #a 
#define STRINGIFY(str) R STRINGIFY1(lit(str)lit) 

这将所有正确的东西放在正确的位置确实将块压缩为一行。我开始认为宏不能在这里使用。

【问题讨论】:

  • 不清楚您要做什么。你能举一个输入和期望输出的例子吗?
  • 你不能(#总是输出旧文字),玩得开心。
  • 正如@n-m 所说,目前无法真正说出您希望实现的目标,因此示例输入和所需输出会很方便:) 只是想知道是否有使用宏进行编码的特定原因?因为您无法像使用函数那样轻松地调试或控制它们。
  • 这毫无意义。原始文字和正确转义的“常规”文字(如# 生成的文字)无法区分。
  • 正如@CatPlusPlus 所说,您不能使用宏,这取决于您要实现的实际目标,如果您真的想从中调用 constexpr 函数,则可能会更好用于向后兼容的 STRINGIFY 宏。

标签: c++ c++11 macros


【解决方案1】:

这不是您所要求的,而是 @R。 Martinho Fernandes 建议您可以使用原始文字:

const char *ptr = R"(
text
here
)"

【讨论】:

  • +1:这是唯一明智的做法。目前尚不清楚为什么需要宏,因此,当原始字符串文字已经明确提供此功能时,为什么要跳过箍以使其按需要工作就更不清楚了。这就是它们被添加到语言中的原因。
【解决方案2】:

不可能以您想要的方式保留换行符,因为 stringise 运算符会显式丢弃它们。在之前的任何翻译阶段都无法访问它们,也无法在以后的翻译阶段恢复它们。

[cpp.stringize]¶2 [...] 参数的预处理标记之间每次出现的空白都会成为字符串文字中的单个空格字符。删除第一个预处理标记之前和包含参数的最后一个预处理标记之后的空白。 [...]

您也许可以编写一个 constexpr 函数,通过根据一些启发式发明换行符来构建修改后的字符串文字,但您永远无法恢复原始换行符。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-01-17
    • 2017-06-17
    • 1970-01-01
    • 2011-02-27
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多