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。

 

posted @ 2022-10-26 00:35  lypbendlf  阅读(358)  评论(0编辑  收藏  举报