在Visual C ++上使用NOMINMAX的可能的问题

在我的程序中定义NOMINMAX之前,我能得到什么问题?

据我所知,这将使得<Windows.h>不定义minmaxmacros,使得与STL的许多冲突,例如std::min()std::max()std::numeric_limits<T>::min()已解决。

我认为只有Windows特定的代码和遗留代码会有问题吗? 几乎所有的库都不应该将min()max()定义为macros?

编辑:将有其他Windows头文件的问题?

使用NOMINMAX是包含<windows.h>的唯一不是完全邪恶的方法。 你还应该定义UNICODESTRICT 虽然后者是由现代实现默认定义的。

但是,你可以遇到微软头文件的问题,例如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;