有没有办法使用预处理器将文本资源拉入原始字符串文字?

πάν*_*ῥεῖ 5 c++ string-literals c-preprocessor c++11

我刚刚注意到我为这个问题给出的答案实际上不起作用:

无论是否使用 CMake,以下内容都适用于当前标准:

std::string resource = R"(
#include "text.txt"
)";
Run Code Online (Sandbox Code Playgroud)

我认为预处理器会首先识别#include "text.txt"语句并扩展文本。

但显然事实并非如此,结果为

std::cout << resource << std::endl;
Run Code Online (Sandbox Code Playgroud)

#include "text.txt"
Run Code Online (Sandbox Code Playgroud)

我尝试使用一些宏来让#include语句在其中展开,但它也不起作用:

#include <string>
#include <iostream>

#define RESOURCE_DEFINIION(resource_var,resource_name) \
    const std::string resource_var = R"xxx( \
    #include resource_name \
    )xxx";

RESOURCE_DEFINIION(resource,"text.txt")

int main()
{
   std::cout << resource << std::endl; 

   return 0;
}
Run Code Online (Sandbox Code Playgroud)

输出是

\                                                                                                                                                                                          
    #include resource_name \                                                                                                                                                                
Run Code Online (Sandbox Code Playgroud)

这是要玩的演示


是否有任何技巧可以text.txt使用预处理器或任何其他常规 C++ 语言功能将资源提取到 c++-11 原始字符串文字中?


免责声明:

我很清楚上述样本有什么问题,以及为什么会以这种方式失败。预处理器忽略出现在"成对中的东西是一个问题。

那么有没有办法让预处理器看到这些?

Rev*_*lot 5

在标准 C++ 中似乎不可能

问题 0:只有标准的文本包含方式才是#include指导性的。

问题 1:字符串字面量是一个预处理标记,在阶段 3 中被识别,因此在阶段 4 中执行预处理指令时,已经确定它#include是字符串文字的一部分,而不是预处理指令。

preprocessing-token:
    header-name
    identifier
    pp-number
    character-literal
    user-defined-character-literal
    string-literal
    user-defined-string-literal
    preprocessing-op-or-punc
    每个不能是其中之一的非空白字符以上

问题2:无法在源代码中引入预处理指令并通过宏替换来执行它:

16.3.4/3
生成的完全宏替换的预处理标记序列不会作为预处理指令处理,即使它类似于一个

所以你不能#include在宏内部工作。

问题 3:宏替换列表应该是一个有效的预处理标记:

control-line:
    # 定义标识符替换列表换行
替换列表:
        pp-tokens opt
pp-tokens:
    preprocessing-token
    pp-tokens preprocessing-token

并且字符串文字本身就是一个预处理标记,您不能从多个宏构建字符串文字。