cppreference Replacing text macros
# and ## operators
NOTE:
1、原文的内容, 非常冗长,不易阅读理解
# stringify and ## concatenate
关于此,参见:
gsl-lite/include/gsl/gsl-lite.hpp
#define gsl_lite_MAJOR 0
#define gsl_lite_MINOR 38
#define gsl_lite_PATCH 0
#define gsl_lite_VERSION gsl_STRINGIFY(gsl_lite_MAJOR) "." gsl_STRINGIFY(gsl_lite_MINOR) "." gsl_STRINGIFY(gsl_lite_PATCH)
#define gsl_STRINGIFY( x ) gsl_STRINGIFY_( x )
#define gsl_STRINGIFY_( x ) #x
#define gsl_CONCAT_( a, b ) gsl_CONCAT2_( a, b )
#define gsl_CONCAT2_( a, b ) a##b
stackoverflow # and ## in macros
NOTE:
1、非常好的例子
#include <stdio.h>
#define f(a,b) a##b
#define g(a) #a
#define h(a) g(a)
int main()
{
printf("%s\n", h(f(1,2)));
printf("%s\n", g(f(1,2)));
return 0;
}
NOTE:
下面是我的测试:
#define f(a,b) a##b #define g(a) #a #define h(a) g(a) int main() { printf("%s\n", h(f(1,2))); printf("%s\n", g(f(1,2))); return 0; }
gcc -E test.cpp# 1 "test.cpp" # 1 "<built-in>" # 1 "<命令行>" # 1 "/usr/include/stdc-predef.h" 1 3 4 # 1 "<命令行>" 2 # 1 "test.cpp" int main() { printf("%s\n", "12"); printf("%s\n", "f(1,2)"); return 0; }
A
NOTE:
1、这个解释非常好
An occurrence of a parameter in a function-like macro, unless it is the operand of # or ##, is expanded before substituting it and rescanning the whole for further expansion. Because g's parameter is the operand of #, the argument is not expanded but instead immediately stringified ("f(1,2)"). Because h's parameter is not the operand of # nor ##, the argument is first expanded (12), then substituted (g(12)), then rescanning and further expansion occurs ("12").
A
Because that is how the preprocessor works.
A single '#' will create a string from the given argument, regardless of what that argument contains, while the double '##' will create a new token by concatenating the arguments.
Try looking at the preprocessed output (for instance with gcc -E) if you want to understand better how the macros are evaluated.
Example
2、More C++ Idioms/Member Detector