问题
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?
回答1:
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.
来源:https://stackoverflow.com/questions/37622767/is-there-a-way-to-pull-in-a-text-resource-into-a-raw-string-literal-using-the-pr