为什么包含Windows.h时std :: min失败?


Answers:


155

windows.h头文件(或更正确地说windef.h,它包括反过来)具有用于宏minmax被干扰。

你应该 #define NOMINMAX在包含它之前。


27
MACROS之所以邪恶的原因之一。:D
Nawaz

7
我使用了整个项目范围内的/ D“ NOMINMAX”
Micka,

@Micka:您将此选项放在项目设置中的什么位置?我必须使用相同的选项,而且我不知道在哪里放置...
flaviu2

页面上所有汇总命令汇总的“其他命令”字段中的@ flaviu2不正确。但目前无法检查
Micka

因为要添加:#include <algorithm> + NOMINMAX
user63898 '18

89

无需定义任何内容,只需使用以下语法绕过宏:

(std::min)(a, b); // added parentheses around function name
(std::max)(a, b);

1
谢谢,这是对我有用的解决方案。我正在编写不能简单地使用NOMINMAX的代码,因为该代码的某些部分使用了需要宏的Windows绘图代码。
米卡·吉马良斯

你能解释为什么围绕魔术的括号可以打败邪恶的宏!不错
陈OT 2015年

1
我不完全了解幕后的所有魔力,但我相信宏解析器正在寻找完全替换“ min(”)的功能,因此宏解析器将忽略“ min()”。无意义()的不会引起任何问题之外宏。
多网

1
简洁的解决方案,但不能解决具有名称min或的函数的问题max(示例用例:实现适合UniformRandomNumberGenerator概念的类)。
Nik Bougalis,2015年

请查看Erik的答案,我认为这是一个更好的解决方案。更少hacky,更清晰。
PolyMesh

28

如其他提到的,错误是由于在Windows标头中定义的最小/最大宏引起的。有三种禁用它们的方法。

1)#define NOMINMAX在包含标头之前,通常这是定义宏以影响以下标头的一种糟糕技术;

2)NOMINMAX在编译器命令行/ IDE中定义。这个决定的坏处在于,如果您想运送自己的货源,则需要警告用户也要这样做。

3)在使用宏之前,只需在代码中取消定义宏

#undef min
#undef max

这可能是最便携式和灵活的解决方案。


2
选项1的另一个问题是它并不总是有效。可能还有其他实际需要它的其他Windows标头,例如gdiplus.h。在这种情况下,选项3可能是您唯一的希望。
shawn1874 2014年

27

有时我仍然会遇到Windows标头的麻烦,并且NOMINMAX的项目范围的定义似乎并不总是有效。作为使用括号的替代方法,有时我使类型明确,如下所示:

int k = std::min<int>(3, 4);

这也使预处理器无法与匹配,min并且比括号解决方法更具可读性。


3
我同意,这是最好的解决方案。当我看到有人殴打我时,我只是想再给一个答案。
PolyMesh

16

尝试这样的事情:

#define NOMINMAX
#include <windows.h>

默认情况下,windows.h定义minmax作为宏。扩展这些代码后,尝试使用的代码std::min(例如)将最终看起来像这样:

int k = std::(x) < (y) ? (x) : (y);

错误消息告诉您std::(x)不允许这样做。


5

就我而言,项目未包含windows.h或未windef.h明确包含。它正在使用Boost。因此,我通过转到项目Properties -> C/C++ -> Preprocessor并添加NOMINMAXPreprocessor Definitions(VS 2013,VS 2015)解决了该问题。


对于VS 2015,在文件中定义宏对我不起作用。在项目中定义有效。
qqqqq

3

对于包括windows.h在内的人员,请将以下内容放入有效的标题中:

#include windows headers ...

pragma push_macro("min")
pragma push_macro("max")
#undef min
#undef max

#include headers expecting std::min/std::max ...

...

pragma pop_macro("min")
pragma pop_macro("max")

在源文件中,仅#undef最小值和最大值。

#include windows headers ...

#undef min
#undef max

#include headers expecting std::min/std::max ...


1

我假设windows.h确实将min定义为宏,例如

#define min(a,b)  ((a < b) ? a : b)

这将解释错误消息。


1

为了解决这个问题,我只创建了fix_minmax.h 没有包含保护的命名头文件

#ifdef max
    #undef max
#endif

#ifdef min
    #undef min
#endif

#ifdef MAX
    #undef MAX
#endif
#define MAX max

#ifdef MIN
   #undef MIN
#endif
#define MIN min

#include <algorithm>
using std::max;
using std::min;

基本用法是这样的。

// Annoying third party header with min/max macros
#include "microsoft-mega-api.h"
#include "fix_minmax.h"

这种方法的优点是,它可以与每种包含的文件或部分代码一起使用。这也节省了您处理依赖于min/ max宏的代码或库时的时间

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.