原理很简单,就是要骗过编译器,让编译器觉得不是冲突的那个宏名字符号.
== 以下的例子假设都已经定义了宏 test ,这个宏名字的污染已经导致我们定义不了 test符号了.
== 即已经有了 #define test "MarcoTestExist" 的宏定义语句存在.
1. 符号定义时的冲突解决方案
1.1. 名字包装. <我经常使用的一种方法>
int (test)() { return 10; } // 用圆括号包装test, 编译器看到 "(test)" 和 "test" 是不一样的符号.
当然你可以使用其他的包装方式, 比如干脆就加个前缀, 比如 int my_test(){...}.
我建议还是使用圆括号来包装, 这样来包装的话, 你还是可以正常的使用 test 这个符号.
1.2. 使用宏的技术 < 这一招是从boost里面学到的, 这里还是以boost里面的符号名称为例. >
#define BOOST_PREVENT_MACRO_SUBSTITUTION
int test BOOST_PREVENT_MACRO_SUBSTITUTION() { return 10; }
我这里只是简单的定义 BOOST_PREVENT_MACRO_SUBSTITUTION 为空, 这样已经足以骗过编译器了.boost里面的实现就不那么单纯, 如果读者有兴趣, 可以自行去研究.
2. 使用符号时冲突的解决方案
1.1. 名字包装. <我经常使用的一种方法,原理同上.>
cout << (test)() << endl;
1.2. 使用宏的技术 < 原理同上. >
#define BOOST_PREVENT_MACRO_SUBSTITUTION
cout << test BOOST_PREVENT_MACRO_SUBSTITUTION() << endl;
3. 一个完整的测试样例 < vc2005验证通过 >
#define test(A,B) ( "call macro test" )
#define BOOST_PREVENT_MACRO_SUBSTITUTION
// #include
char* (test)(int a, int b)
{ return "call function test"; }
namespace ns
{
char* test BOOST_PREVENT_MACRO_SUBSTITUTION(int a,int b)
{ return "call function ns::test"; }
}
int main ( int, char ** )
{
cout << test (1,2) << endl; // call macro test
cout << (test)(1,2) << endl; // call function test
cout << (ns::test)(1,2) << endl; // call function ns::test
cout << test BOOST_PREVENT_MACRO_SUBSTITUTION(1,2) << endl; // call function test
cout << ns::test BOOST_PREVENT_MACRO_SUBSTITUTION(1,2) << endl; // call function ns::test
return 0;
}
阅读(2916) | 评论(0) | 转发(0) |