web-dev-qa-db-fra.com

Comment gérer la macro max dans windows.h en collision avec max dans std?

J'essayais donc d'obtenir une entrée entière valide de cin et j'ai utilisé une réponse à cette question .

Il a recommandé:

#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);
}

Ce qui me donne une erreur sous Windows, disant que la macro max ne prend pas autant d'arguments. Ce qui signifie que je dois faire ça

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);

Pour le faire fonctionner. C'est assez moche; existe-t-il une meilleure façon de contourner ce problème? Peut-être que je devrais stocker la définition de max et la redéfinir ensuite?

52
Almo

Définissez la macro NOMINMAX :

Cela supprimera les définitions min et max dans Windef.h.

83
hmjd

Mettez simplement le nom de la fonction entre parenthèses:

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

Pas besoin de la macro NOMINMAX dans ce cas, et vous n'aurez pas d'avertissements du compilateur

54
NIRO

Essayez-vous simplement de vider le tampon cin? J'ai toujours juste utilisé:

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

Si vous ne savez pas si quelqu'un d'autre aurait pu inclure windows.h sans NOMINMAX, vous pouvez définir une macro factice qui peut être utilisée pour supprimer les invocations de macro de type fonction sans changer la définition:

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

Pas vraiment joli non plus, mais fonctionne et est non intrusif.

Lorsque je travaille avec le fichier d'en-tête Windows, je préfère le cacher autant que possible en l'incluant uniquement dans le code spécialisé et les fichiers d'en-tête (en utilisant pimpl si nécessaire), car il jette tout simplement trop de déchets dans l'espace de noms global.

8
Philipp

Si vous utilisez GDI +, l'approche avec NOMINMAX ne fonctionnera pas pour vous, car les en-têtes de GDI + nécessitent min ou max dans l'espace de noms global.

Et la solution de contournement la plus simple dans ce cas consiste à annuler la définition de min/max lorsqu'elles ne sont plus nécessaires.

L'exemple de code pour illustrer l'approche:

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