I am looking for general solution to the problem as stated in the title. But as illustration consider my real case. I would like to get wstring
, like this:
L"hello"
but when I have a macro:
#define MACRO(S) ...
and a call:
MACRO("hello") // no L prefix
how to define it to get wstring
, as before?
L S
is treated as 2 symbols.
You need the paste operator, look up # and ## for the pre-processor for exciting new opportunities to both solve problems and create interesting new ones.
http://www.cprogramming.com/reference/preprocessor/token-pasting-operator.html
but for your specific question, try:
#define MACRO(S) L ## S
In my personal experience, the paste operator is one of the best genuine uses for macros in C++ since it gives you something you can't easily do without it. But like most pre-processor features, it is often used for evil.
As a history note, there were early C compilers where you could write #define MACRO(S) L/* */S
which people did, because they legitimately wanted token pasting, but it didnt formally exist. I believe these days the comment hack will explicitly not work in standard complying pre-processors.
The straightforward way is to use preprocessor token pasting , the ##
preprocessor operator, as follows:
#define MACRO( s ) L ## s
You state that you're looking for a "general solution", and the basic token pasting isn't very general.
In particular the straightforward macro gets awkward when you want to define a long string like
L"Blah blah\n"
L"Second line\n"
L"Third line"
You'd then have to write eg
MACRO( "Blah blah\n" )
MACRO( "Second line\n" )
MACRO( "Third line" )
Happily you can use C++11 variadic macros to support an arbitrary number of arguments, writing the above literal like this:
MACRO(
"Blah blah\n",
"Second line\n",
"Third line"
)
with MACRO
defined as just, for example,
# define WITH_L_PREFIX_( lit ) L##lit
# define MACRO( ... ) MM_APPLY( WITH_L_PREFIX_, __VA_ARGS__ )
Then the problem is reduced to defining MM_APPLY
, eg like this:
#define MM_APPLY( macroname, ... ) \
MM_INVOKE( \
MM_CONCAT( MM_APPLY_, MM_NARGS( __VA_ARGS__ ) ), \
( macroname, __VA_ARGS__ ) \
)
which in turn reduces the problem to defining MM_INVOKE
, MM_CONCAT
, MM_NARGS
, and the more specific MM_APPLY_1
through eg MM_APPLY_21
, or whatever your preferred limit on number of arguments is. The reason for this is mainly to support the Visual C++ preprocessor, which isn't quite standard-conforming.
Regarding MM_ARGS
, which produces the number of arguments, see original code by Laurent Deniau, " VA_NARG ," 17 January 2006, in the Usenet group <comp.std.c>, eg as archived at ( https://groups.google.com/forum/?fromgroups=#!topic/comp.std.c/d-6Mj5Lko_s ).
For the rest, starting with MM_APPLY_
n , these definitions look like…
#define MM_APPLY_1( macroname, a1 ) \
MM_INVOKE_B( macroname, (a1) )
#define MM_APPLY_2( macroname, a1, a2 ) \
MM_INVOKE_B( macroname, (a1) ) \
MM_APPLY_1( macroname, a2 )
#define MM_APPLY_3( macroname, a1, a2, a3 ) \
MM_INVOKE_B( macroname, (a1) ) \
MM_APPLY_2( macroname, a2, a3 )
which, again for reasons of supporting a specific compiler (namely g++ this time) introduces MM_INVOKE_B
.
#define MM_INVOKE( macro, args ) macro args
#define MM_INVOKE_B( macro, args ) macro args // For nested invocation with g++.
MM_CONCAT
is simple,
#define MM_CONCAT__( a, b ) a ## b
#define MM_CONCAT_( a, b ) MM_CONCAT__( a, b )
#define MM_CONCAT( a, b ) MM_CONCAT_( a, b )
And that's that, roughly.
This constitutes a little "macro framework" to apply an operation to each argument.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.