一个关于宏处理中 ##与#的问题
本帖最后由 amber1314 于 2012-12-04 16:14:33 编辑 前提只用宏处理,其实不确定只用宏到底能不能解决,所以来求救.
我想到得如下一个标识
L"C:\\Data\\Others\\foobar"
#defineDIRECTORY"C:\\Data\\Others\"
#defineLOGPATH(a)DIRECTORY ## #a
这样LOGPATH(foobar) 可以得到串 "C:\\Data\\Others\\foobar"
然后想在前面加个一个大写 L, 然后想整个串怎么处理一下输出或者不输出只在前面加上L也成.
下面代码里有个问题是 ## 连接符后面的宏没法再展开了
或者输出的字符串为啥没把两个连续的字符串连起来
#include <string>
#include <iostream>
using namespace::std;
#defineDESTINATION"L"C:\\\\Data\\\\Others\\\\foobar""
#defineDIRECTORY"C:\\Data\\Others\"
#defineLOGPATH(a)DIRECTORY ## #a
#defineTOSTR(a) #a
#defineMACROTOSTR(a)TOSTR(a)
#defineCOMBINE(a, b)a ## b
#defineCOMBINE1(a, b, c)a ## b ## #c
int main(int argc, char* argv[])
{
cout << LOGPATH(foo) << endl;// test
/* 下面试了各种方式都没解决,远不只这两种 */
cout << MACROTOSTR( COMBINE(L, LOGPATH(bar)) ) << endl;
cout << MACROTOSTR( COMBINE1(L, "C:\\Data\\Others\", foobar) ) << endl;
cout << "\nWhat i want is: \n" << DESTINATION << endl;
return 0;
}
printf("%s\n", h(g(f(1,2)))); // "f(1,2)"
printf("%s\n", h(h(f(1,2)))); // "12"
system("pause");
return 0;
}
预处理后的:(在编译选项中添加/EP /P后编译生成的.i文件)
int main()
{
char a = 'a';
cout<<"a"<<endl;
cout<<"g(a)"<<endl;
printf("%s\n", "12");
printf("%s\n", "f(1,2)");
printf("%s\n", "h(f(1,2))");
printf("%s\n", ""f(1,2)"");
printf("%s\n", ""12"");
system("pause");
return 0;
}
---------------------------------------------------
宏解析
1. ##操作符
##操作符它的作用是在替代表中将其前后的参数连接成为一个预处理符号,它不能出现于宏替代表的开端和末尾。
例:
#define concat(s,t) s##t
#define AAA ABC
concat(A, AA)
将被替换成
ABC
2. 重新扫描和替换
在替换列表中的所有参数替换过之后,预处理器将对结果token序列重新扫描以便对其中的宏再次替换。
当正在替换的宏在其替换列表中发现自身时,就不再对其进行替换。在任何正在嵌套替换的宏的替换过程中遇到正被替换的宏就对其不再进行替换(防止递归)。
例:
#define ROOT AAA CCC
#define AAA ROOT
ROOT
将被替换成
ROOT CCC