#define NOMINMAX 使用 std::min/max

Posted

技术标签:

【中文标题】#define NOMINMAX 使用 std::min/max【英文标题】:#define NOMINMAX using std::min/max 【发布时间】:2012-11-05 04:02:20 【问题描述】:

我最近添加了:

#define NOMINMAX
#include <Windows.h>
#include <algorithm>

到我的 main.cpp 以便使用

std::max( x , x ); // x is just a placeholder and not actual anything
std::min( x  , x );

但我不能在其他文件中使用std::max()/std::min()

error C2589: '(' : illegal token on right side of '::'
error C2059: syntax error : '::'

我尝试在我的其他文件中添加#define NOMINMAX,但失败了。线索是什么?

问之前看了一圈,没看懂答案Possible problems with NOMINMAX on Visual C++

【问题讨论】:

任何包含 windows.h 并使用算法版本的内容,如果尚未定义,则应在包含之前定义。 为什么不把代码贴在它不工作的文件上,而不是把代码贴在它工作的文件上!真的,除非您发布,否则我们看不到您的代码。 而且您确定那些 “其他文件” 不包括 &lt;windows.h&gt; 并且之前没有定义 NOMINMAX(可能是通过其他一些标头间接地)? @john,这是一个 5 行帧计时器代码,没什么特别的。谢谢 特别说明;值得注意的是,您可以在#include &lt;Windows.h&gt; 之后使用#undef NOMINMAX。这将减少很多混乱。 #define WIN32_LEAN_AND_MEAN 相同。 #define NOMINMAX 以一种有趣的方式充当 Windows.h 的“论据”。 #undef NOMINMAX 就像事后清理堆栈一样,以一种有趣的方式。未来包括始终通过不发送垃圾邮件警告来感谢您。 【参考方案1】:

如果您真的很绝望,请在函数名称周围加上括号:

(std::min)(x, y);

此语法不会应用类似函数的宏。 (正式地,要应用类似函数的宏,宏的名称必须后跟可选的空格,然后是'('。)

【讨论】:

【参考方案2】:

通过编译器标志定义NOMINMAX

> cl.exe -DNOMINMAX ...

这将为所有源文件定义。我不使用 IDE,但此页面提供了有关导航 IDE 以进行设置的指南:Using STL in Windows Program Can Cause Min/Max Conflicts :

只需定义 NOMINMAX 预处理器符号。这可以在 Developer Studio 项目中的 Build、Settings 下的 C/C++ 选项卡的 Preprocessor 类别中完成。这将抑制 Windef.h 中的最小和最大定义。

【讨论】:

通过编译器标志定义NOMINMAX: > cl.exe -DNOMINMAX ... 导致以下大约 12 行 ... 1>c:\program files\microsoft sdks\windows\v7 .0a\include\gdiplustypes.h(470): error C3861: 'min': identifier not found i´m using the GDI stuff。谢谢 NaturalDemon,这里有你的问题的解决方案 -- ***.com/a/4914108/867349【参考方案3】:

如果您定义 NOMINMAX,因为您更喜欢 STL 版本,那么在包含使用 min/max 宏的 gdiplus.h 时可能会遇到问题。 作为解决方案,您需要包含 STL 标头并在包含 gdiplus.h 之前使用“使用命名空间 std”

例如:

#define NOMINMAX

// Include C++ headers
#include <algorithm>
using namespace std;

// Include Windows headers
#include <windows.h>
#include <gdiplus.h>

【讨论】:

或者如果您不想过多地污染全局命名空间,using std::min; using std::max; 可能是更好的解决方案。 std::min/max 与宏不同,要求两个参数的类型相同。这可能并不总是适用于所有使用宏的库。更好的解决方案是不定义NOMINMAX,包括Windows.h 和所有需要这些宏的库,然后是#undef min/max。因此,包含的库可以正常工作,并且没有全局命名空间污染。【参考方案4】:

很可能你的问题是你#define NOMINMAX 在你#include "windows.h" 之后。重要的是 #define 先出现。

原因是windows.h(其实我认为windef.h,是windows.h包含的)有类似这样的代码:

#ifndef NOMINMAX
#define min(x,y) ((x) < (y) ? (x) : (y))
#define max(x,y) ((x) > (y) ? (x) : (y))
#endif

所以#define NOMINMAX 是告诉编译器(或实际上是预处理器)跳过minmax 的定义,但只有在#include "windows.h" 之前这样做才适用。

【讨论】:

以上是关于#define NOMINMAX 使用 std::min/max的主要内容,如果未能解决你的问题,请参考以下文章

是否可以通过#define 将 g++ 设置为遵循 C++11 ISO (-std=c++11)?

C++学习(三三二)std::ios::binary

STL源码学习std::list类的类型别名分析

std::string 源代码中宏的使用

为啥不能对 std::vector 使用前向声明?

VS2015--win32工程配置的一些想法之GdiplusTypes.h(470) : error C3861: 'min': identifier not found