在我的程序中定义NOMINMAX
之前,我能得到什么问题?
据我所知,这将使得<Windows.h>
不定义min
和max
macros,使得与STL的许多冲突,例如std::min()
, std::max()
或std::numeric_limits<T>::min()
已解决。
我认为只有Windows特定的代码和遗留代码会有问题吗? 几乎所有的库都不应该将min()
和max()
定义为macros?
编辑:将有其他Windows头文件的问题?
使用NOMINMAX
是包含<windows.h>
的唯一不是完全邪恶的方法。 你还应该定义UNICODE
和STRICT
。 虽然后者是由现代实现默认定义的。
但是,你可以遇到微软头文件的问题,例如GdiPlus。 我不知道任何其他公司或个人的头问题。
如果头文件像GdiPlus那样定义了一个名称空间,那么一个修正是为相关的头文件(包含<algorithm>
地方)创建一个包装器,并在头文件的名称空间内using namespace std;
(或者using std::min;
并using std::max
):
#define NOMINMAX #include <algorithm> namespace Gdiplus { using std::min; using std::max; }
请注意,这是非常不同于using namespace std;
在全球范围内,这是不应该做的 。
对于没有命名空间的情况,我不知道有什么好的解决方法,但是我并没有遇到这种情况,所以实际上这个问题可能是没有意义的。
我通常使用NOMINMAX
来限制潜在的副作用:
#define NOMINMAX #include <windows.h> #undef NOMINMAX
这样, NOMINMAX
的范围就相对狭窄了。
这不是一个完美的解决方案。 如果其他东西已经定义了NOMINMAX
,这个模式就失败了(尽管我从来没有遇到这种情况)。
如果你想真的很小心,那么你可以#include包装头,无论你将#included windows.h。 包装会像这样:
/* Include this file instead of including <windows.h> directly. */ #ifdef NOMINMAX #include <windows.h> #else #define NOMINMAX #include <windows.h> #undef NOMINMAX #endif
你也可以想象在包装中做其他事情,比如强制UNICODE
和/或STRICT
。
对于预编译头(像stdafx.h),我使用这个:
#define NOMINMAX #include <algorithm> #include <Windows.h> #ifndef min #define min(x,y) ((x) < (y) ? (x) : (y)) #endif #ifndef max #define max(x,y) ((x) > (y) ? (x) : (y)) #endif #include <gdiplus.h> #undef min #undef max
我通过按以下顺序声明头和名称空间来解决问题:
#include <windows.h> #include <minmax.h> #include <gdiplus.h> using namespace Gdiplus; using namespace std;