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

Alm*_*lmo 54 c++ iostream cin

所以我试图从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);
}
Run Code Online (Sandbox Code Playgroud)

这给了我一个关于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);
Run Code Online (Sandbox Code Playgroud)

让它工作.那太难看了; 有没有更好的方法来解决这个问题?也许我应该存储它的定义max并在之后重新定义它?

hmj*_*mjd 88

定义宏NOMINMAX:

这将抑制Windef.h中的最小和最大定义.

  • 由于某种原因,该网址对我不起作用,即使它返回为仅命中:https://support.microsoft.com/en-us/search?query=NOMINMAX (4认同)

小智 59

只需将函数名称括在括号中:

(std::numeric_limits<size_type>::max)()
Run Code Online (Sandbox Code Playgroud)

在这种情况下不需要NOMINMAX宏,另外你不会收到编译器警告

  • @DaleWilson是的,你错过了一些东西.您的通话将获得两个值中较大的值.std :: numeric_limits <size_type> :: max()将返回size_type可以存储的最大值. (3认同)
  • `std::max&lt;size_type&gt;(a,b)` 对我有用并且更具可读性。模板参数抑制宏。我错过了什么吗? (2认同)
  • 在parens中包装函数名称是获取函数指针并调用它,就好像通过函数指针实现策略模式一样.这违背了[直接在代码中表达想法]的建议(https://github.com/isocpp/CppCoreGuidelines/blob/master/CppCoreGuidelines.md#p1-express-ideas-directly-in-code),因为这个其他语法是而是试图解决min和max宏的定义(不是通过函数指针实现策略模式).Clang/LLVM基础结构在任何Windows标头之前建议"#define NOMINMAX".哪个是IMO更好的建议. (2认同)
  • @LouisLangholtz 对于 VS 项目,有通用的 stdafx.h,当您将 NOMINMAX 放入其中时,使用宏的其他文件中可能会出现错误。 (2认同)

Lit*_*tor 9

你只是想冲洗cin缓冲区吗?我一直用过:

cin.ignore(cin.rdbuf()->in_avail());
Run Code Online (Sandbox Code Playgroud)


Phi*_*ipp 8

如果你不知道别人可能不包括windows.h没有NOMINMAX,你可以定义一个虚拟的宏可以用来抑制函数宏调用不改变的定义:

#define DUMMY
...
std::numeric_limits<std::streamsize>::max DUMMY ()
Run Code Online (Sandbox Code Playgroud)

也不是很漂亮,但是有效并且是非侵入性的.

使用Windows头文件时,我更喜欢通过将其包含在专门的代码和头文件中(如果需要,使用pimpl)来尽可能地隐藏它,因为它会向全局命名空间抛出太多垃圾.

  • 有趣.我一定会遵循建议,尽可能剥离windows.h. (2认同)

Ant*_*onK 6

如果您碰巧使用 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>
Run Code Online (Sandbox Code Playgroud)