2009-09-08 10 views
17

Ich habe ein Problem, dass std :: numeric_limits :: min() Konflikte mit dem "min" Makro in "windef.h" definiert. Gibt es eine Möglichkeit, diesen Konflikt zu lösen, ohne das Makro "min" zu deaktivieren. Der Link unten gibt einige Hinweise, jedoch konnte ich keine Klammern mit einer statischen Elementfunktion verwenden.Makro und Member-Funktion Konflikt

What are some tricks I can use with macros?

Vielen Dank im Voraus.

+8

Warum funktioniert der Klammertrick nicht für Sie? Denken Sie daran, es um den gesamten Ausdruck zu wickeln, wie in '(std :: numeric_limits :: min)()' –

+0

Dies funktionierte. Vielen Dank. Bitte schicke es als Antwort, ich möchte es akzeptieren. – msh

+0

Vielen Dank, ich kann nicht glauben, dass ich schon seit Jahren mit #undefs herumgestreift habe, bevor jemand das angesprochen hat ... – Roel

Antwort

29

Die Abhilfe ist die Klammer zu verwenden: int max = (numeric_limits<int>::max)();

Es Sie sind erlaubt Die windef.h, erfordert Sie nicht zu #undef max (die nachteilige Nebenwirkungen haben kann) und es gibt keine Notwendigkeit, #define NONIMAX. Klappt wunderbar!

+0

Können Sie erklären, warum das funktioniert? – Derek

+1

Von dem, was ich verstehe, verarbeitet es zuerst den Wert in der Klammer. Das Makro nimmt auch zwei Parameter auf und umschließt die Funktionsklammer, es zeigt keine Parameter für das Makro an. – Apeiron

1

Ja, ich habe das gleiche Problem. Ich habe nur eine Lösung gefunden:

#ifdef min 
#undef min 
#endif //min 

Platzieren Sie es direkt nachdem Includes getan haben.

+2

Beachten Sie, dass das '# ifdef' unnötig ist. Es ist in Ordnung, einen Namen zu definieren, der nicht als Makro definiert ist, also ist "#undef min" sicher, unabhängig davon, ob "min" definiert ist. –

23

Die einzige wirklich allgemeine Lösung ist nicht windows.h in Ihren Kopfzeilen enthalten.

Dieser Header ist ein Mörder, und tut so ziemlich alles, was es kann, um Ihren Code in die Luft zu sprengen. Es wird nicht kompiliert, ohne MSVC-Spracherweiterungen aktiviert, und es ist das schlimmste Beispiel für Makro-Missbrauch, die ich je gesehen habe.

Fügen Sie es in einer einzelnen CPP-Datei ein, und zeigen Sie dann Wrapper in einer Kopfzeile an, die der Rest Ihres Codes verwenden kann. Wenn windows.h nicht sichtbar ist, kann es nicht mit Ihren Namen in Konflikt stehen.

Speziell für den Min/Max-Fall können Sie #define NOMINMAX vor einschließlich windows.h. Es wird dann diese spezifischen Makros nicht definieren.

+1

Abgestimmt, da wir hier zum selben Schluss gekommen sind. Unter anderen Übeln fügt es ungefähr 19K * pro Objektdatei * hinzu. Wir haben gerade unsere eigene Header-Datei mit den wenigen Dingen erstellt, die wir normalerweise von Windows.h brauchen. –

+2

Gute Antwort.Wusste nicht über diese 'NOMINMAX' Tricks. –

+6

Nun, es ist eine typische Microsoft-Lösung ... "Unsere Makros verursachen Ärger? Nun, wir werden nur ein Makro hinzufügen, um sie zu deaktivieren!" ;) – jalf

1

Zusätzlich zu jalfs Antwort können Sie auch #define WINDOWS_LEAN_AND_MEAN vor einschließlich Windows.h. Es wird min, max und etwas mehr Rauschen von Windows-Headern entfernt.

+0

Danke. Aber in meinem Projekt macht das viel mehr Kopfschmerzen. – msh

1

Dewfy, Das Problem mit dieser Lösung ist, wenn Sie die Makro Afteryards verwenden müssen.

Ich habe sogar versucht, die Definition NOMINMAX, aber es hat nicht funktioniert.

Die beste Lösung fand ich derjenige von Johannes Schaub war: (std :: numeric_limits :: min)()

0
#define NOTHING 

int main() 
{ 
    int m = -1; 

    m = max(0, 1); // expands max macro 

    m = max NOTHING (0, 1); // error 'max': identifier not found 
          // functions-like macros are defined as an 
          // identifier immediately followed by a left 
          // parenthesis - N3690/16.3/10 

    m = std::max NOTHING (2, 3); // NOTHING stops the macro 
           // expansion (max is not followed by left 
           // parenthesis): std::max is called 

    m = (std::max)(4, 5); // the enclosing parenthesis stops the macro 
          // expansion (max is not followed by left 
          // parenthesis): std::max is called 

    return 0; 
}