Visual C++上NOMINMAX可能出现的问题

Man*_*uel 33 c++ windows visual-c++

NOMINMAX在我的程序中定义其他任何内容时,我可以遇到什么问题?

据我所知,这将使<Windows.h>没有定义minmax宏,从而与STL许多矛盾,例如std::min(),std::max()std::numeric_limits<T>::min()得到解决.

我是否正确地假设只有Windows特定和遗留代码会出现问题?几乎所有的库都不应该依赖min()max()定义为宏?

编辑:其他Windows标题是否会出现问题?

Che*_*Alf 57

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

但是,您可能会遇到Microsoft的标题问题,例如GdiPlus.我不知道任何其他公司或人员的标题问题.

如果标题定义了一个命名空间,如GdiPlus的话,那么一个解决方法是创建相关的头,在那里你有一个包装<algorithm>,并标头的命名空间内,using namespace std;(或可替代using std::min;using std::max):

#define NOMINMAX
#include <algorithm>
namespace Gdiplus
{
  using std::min;
  using std::max;
}
Run Code Online (Sandbox Code Playgroud)

请注意,这using namespace std;与标题中的全局范围非常不同,后者应该永远不会这样做.

对于没有命名空间的情况,我不知道有什么好的解决方法,但很高兴我没有遇到过这种情况,所以在实践中这个问题可能没什么问题.

  • @bobobobo:放弃`std :: min`和`std :: max`对于小型个人程序来说可能不是什么大问题,但这意味着放弃使用它们的任何头模块库.这对于专业工作来说是不可接受的.这不是一个现实的选择. (14认同)
  • 不仅如此,还有一些有用的东西,比如numeric_limits <T> :: min和max,它们与min和max宏完全不同. (6认同)

Adr*_*thy 14

我通常使用NOMINMAX这样来限制潜在的副作用:

#define NOMINMAX
#include <windows.h>
#undef NOMINMAX
Run Code Online (Sandbox Code Playgroud)

这样,范围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
Run Code Online (Sandbox Code Playgroud)

你可以想象在包装器中做其他事情,比如强制执行UNICODE和/或STRICT.