有没有办法使用预处理器将文本资源提取到原始字符串文字中? [英] Is there a way to pull in a text resource into a raw string literal using the pre-processor?

查看:76
本文介绍了有没有办法使用预处理器将文本资源提取到原始字符串文字中?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我刚刚注意到我为这个问题实际上不起作用:



无论是否使用CMake ,以下应符合当前标准:

  std :: string resource = R(
#include text.txt
);



我认为-processor首先会识别 #include text.txt 语句并展开文本。



但是显然不是这样,

  std :: cout<<的结果资源<< std :: endl; 


  #include text.txt 


我试图使用一些宏来扩展 #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<<资源<< std :: endl;

返回0;
}

输出为



< blockquote>

  \ 
#include resource_name \


这里是演示






是否有任何欺骗手段可以插入 text.txt 使用预处理程序或任何其他常规c ++语言功能转换成c ++-11原始字符串文字?






免责声明:



我知道上述示例有什么问题以及为什么这些示例无法通过此方法问题是预处理器会忽略 对中出现的东西。



有没有办法

解决方案

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



问题0 :唯一的文本包含方式是 #include 指令。



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


预处理-token:

标头名称

标识符

pp-number

字符文字

用户定义字符字面量

字符串字面量

用户定义的字符串字面量

预处理ng-op-or-punc

。每个非空格字符都不能是上述字符之一


问题2 :不可能将预处理指令引入源代码并通过宏替换执行它:


16.3.4 / 3

结果完全替换为宏的预处理令牌序列即使类似于一个,也不会作为预处理指令处理


因此您不能在宏中使用 #include



问题3 :宏替换列表应该是有效的预处理令牌:


control -line:

#定义标识符替换列表换行

替换列表:

pp令牌选择

pp令牌:

预处理令牌

pp-tokens pr eprocessing-token


而字符串文字本身就是一个预处理令牌,您不能从多个宏中构建字符串文字。


I've just noticed that an answer I have given for this question actually doesn't work:

Regardless of using CMake or not, the following should work with the current standard:

std::string resource = R"(
#include "text.txt"
)";

I thought that the pre-processor would recognize the #include "text.txt" statement in first place and expand the text.

But that's obviously not the case, the result for

std::cout << resource << std::endl;

is

#include "text.txt"

I tried to use some macro to let the #include statement be expanded within, but it doesn't work either:

#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;
}

The output is

\                                                                                                                                                                                          
    #include resource_name \                                                                                                                                                                

Here's the demo to play with


Is there any trickery available to pull in the text.txt resource into a c++-11 raw-string literal, using the pre-processor or any other regular c++ language feature?


Disclaimer:

I well know what's wrong with the above samples and why these fail this way. It's a problem that the pre-processor ignores the stuff appearing within " pairs.

So is there a way to escape these to be seen by the pre-processor?

解决方案

It seems like not possible in standard C++

Problem 0: Only standard way of textual inclusion is #include directive.

Problem 1: String literal is a preprocessing token, which are recognised in phase 3, so when preprocessing directives are executed in phase 4, it is already determined that #include is a part of string literal and not a preprocessing directive.

preprocessing-token:
    header-name
    identifier
    pp-number
    character-literal
    user-defined-character-literal
    string-literal
    user-defined-string-literal
    preprocessing-op-or-punc
    each non-white-space character that cannot be one of the above

Problem 2: It is impossible to bring preprocessing directive in source and execute it by macro substitution:

16.3.4/3
The resulting completely macro-replaced preprocessing token sequence is not processed as a preprocessing directive even if it resembles one

So you cannot have working #include inside macro.

Problem 3: macro replacement list should be a valid preprocessing token:

control-line:
    # define identifier replacement-list new-line
replacement-list:
        pp-tokens opt
pp-tokens:
    preprocessing-token
    pp-tokens preprocessing-token

And string literal is a preprocessing token itself, you cannot build string literal from several macro.

这篇关于有没有办法使用预处理器将文本资源提取到原始字符串文字中?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆