首页 > 代码库 > 解决C++中宏定义导致的名字污染

解决C++中宏定义导致的名字污染

在编写一个 Graph 模板类的时候,为了使用户可以自定义 距离 的类型,比如 int 或者 double 甚至其他高精度有理数的封装类,
我将距离的类型定义为模板参数 T_DIST ,并使用了标准库中的库函数

std::numeric_limits<T_DIST>::max()

来定义最大距离

template <typename T_DIST>
const typename TopologicalGraph<T_DIST>::Distance TopologicalGraph<T_DIST>::MAX_DISTANCE = 
    (std::numeric_limits<T_DIST>::max() / static_cast<T_DIST>(2));

在进行单元测试时,由于另一个在程序崩溃时追踪并记录执行状态的 Trace 类里包含了 Windows.h,
而我使用的是包含模型来实现该模板,且在测试用的工程中 Trace.h 在 Graph.h 之前出现,
导致 std::numeric_limits<T_DIST>::max() 与 Windows.h 中的 max() 宏冲突了,于是在预处理阶段完成的宏替换使该语句出现了莫名其妙的语法错误。

后来上 stackoverflow 查了一下,
有用 #undef max 的,有使用其他windows的编译开关宏的,有在 cpp 文件中包含 Windows.h 的,还有说千万不要包含 Windows.h 的……

最后终于找到了一个优美的解决方案——
http://stackoverflow.com/questions/1394132/macro-and-member-function-conflict

其实只要使用括号将 max 括起来即可……

(std::numeric_limits<T_DIST>::max)()


所以,还是要勤加括号啊~
以前只知道定义宏的时候要一层层地用括号包起来,没想到使用宏或者语法结构和宏类似的语法元素(如函数调用)的时候也要这样!


………………

解决这个问题之后突然发现,好像封装类无法使用 std::numeric_limits<T_DIST>::max() 获得正确的最大值……

解决C++中宏定义导致的名字污染