如何处理 windows.h 中的 max 宏与 std 中的 max 相冲突?

所以我试图从 cin 获得有效的整数输入,并使用了这个 有个问题的答案。

它建议:

#include <Windows.h> // includes WinDef.h which defines min() max()
#include <iostream>
using std::cin;
using std::cout;


void Foo()
{
int delay = 0;
do
{
if(cin.fail())
{
cin.clear();
cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
}
cout << "Enter number of seconds between submissions: ";
} while(!(cin >> delay) || delay == 0);
}

这给了我一个 Windows 上的错误,说 max宏不需要那么多参数。也就是说我必须这么做

do
{
if(cin.fail())
{
cin.clear();
#undef max
cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
}
cout << "Enter number of seconds between submissions: ";
} while(!(cin >> delay) || delay == 0);

让它起作用。这是相当丑陋的; 有没有更好的办法来解决这个问题?也许我应该存储 max的定义,然后重新定义它?

38840 次浏览

定义宏 NOMINMAX:

这将抑制 Windef.h 中的 min 和 max 定义。

你是不是只是想冲洗一下缓冲液? 我一直都是这么说的:

cin.ignore(cin.rdbuf()->in_avail());

如果你不知道其他人是否在没有 NOMINMAX的情况下包含了 windows.h,你可以定义一个虚拟宏,它可以用来抑制类似函数的宏调用,而不需要改变定义:

#define DUMMY
...
std::numeric_limits<std::streamsize>::max DUMMY ()

也不是很漂亮,但是很有效,而且不会打扰到别人。

在使用 Windows 头文件时,我倾向于尽可能多地隐藏它,只将它包含在专门的代码和头文件中(如果需要,使用 pimpl) ,因为它会向全局名称空间抛出太多垃圾。

只要把函数名用括号括起来:

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

在这种情况下,不需要使用 NOMINMAX 宏,而且不会得到编译器警告

如果您碰巧使用 GDI + ,那么使用 NOMINMAX的方法将不适合您,因为 GDI + 的头部需要在全局名称空间中使用 minmax

在这种情况下,最简单的解决办法是在不再需要 min/max时取消它们的定义。

演示该方法的代码示例:

//#define NOMINMAX - this won't work
#include <Windows.h>
#include <gdiplus.h>
#undef max
#undef min
...
#include <cxxopts.hpp>

我来这里寻找 windows.h 定义的常见事物的列表,经过多次搜索,我找到了 min,max,small,near,far。希望这也能帮到其他人。

我知道这个问题已经有10年历史了,但是没有人给出明显的答案,所以这是我处理这个问题的方法。

所有与操作系统相关的内容都放在一个翻译单元(一个 CPP 源文件)中,这个单元为项目的其余部分提供了一个更清晰的 API,因此 windows.h 永远不会污染项目的其余部分。操作系统的任何句柄都只是一个“ NativeHandle”,类型定义为 void * ; 有些东西以这种方式堆分配,这在其他情况下是不可能的,但考虑到这也为移植到其他平台提供了一个单一的源点,这并不是一个很大的缺点。