C++中#和##
转自:https://blog.csdn.net/YhL_Leo/article/details/48879093
1.介绍
C/C++ 的宏中,
#
的功能是将其后面的宏参数进行字符串化操作;
凡是宏定义里有用#
或##
的地方宏参数是不会再展开,
#include <iostream> using namespace std; #define WARN_IF(EXP) if(EXP) cerr << #EXP << endl; #define paster( n ) cout << "token" << #n << " = " << n << endl; #define _CONS(a, b) int(a##+##b) #define _STRI(s) #s int main() { int div = 0; WARN_IF(div == 0); // prints : div == 0 paster(9); // prints : token9 = 9 // cout << _CONS(1, 2) << endl; // pasting "1" and "+" does not give a valid preprocessing token cout << _STRI(INT_MAX) << endl; // prints : INT_MAX return 0; }
输出:
div == 0 token9 = 9 INT_MAX
错误示例1:
不能作为结构体的成员传入,因为.或者->都不是合法的变量标识符。
struct Info{ std::map<uint64_t, std::map<uint16_t, std::string>> pList; }; #define PRINT_INFO(pInfo, keyName) \ for (const auto& item : pInfo.##keyName) { \ cout<<" hh."; \ } #define PRINT_INFO2(pInfo, keyName) \ for (const auto& item : pInfo.#keyName) { \ cout<<" hh."; \ }
这2种用法都是错误的,#因为pInfo."pList"不是数据成员!编译时会报错。##是因为它不能和左边的.作为变量名拼接!.不是有效的标识符字符。
错误示例2:
#define ADD_NAMESPACE(NS,FUNC) NS##::##FUNC ADD_NAMESPACE(std,cout)<<5<<ADD_NAMESPACE(std,endl);//错误用法
因为它是定义一个整体的字符串,"std::cout<<5<<std::endl",编译器是无法解析的。
参考:https://stackoverflow.com/questions/27361170/pasting-and-foo-does-not-give-a-valid-preprocessing-token
2. ## 例子
- ## 功能是在带参数的宏定义中将两个子串联接起来,从而形成一个新的子串。但它不可以是第一个或者最后一个子串。
https://blog.csdn.net/xdsoft365/article/details/5911596
## (token-pasting)符号连接操作符。
#define exampleNum(n) num##n int num9=9; int num=exampleNum(9); //将会扩展成 int num=num9;
上述例子中,num##n即num9,已经定义了num9,所以num值被初始化为9。