Frage

Ich habe ein Problem mit meinem Klemme Makro, wenn, wenn mein Wert ist über 10 und meine hoch ist über 17 es nicht mehr funktioniert. Jede Idee?

#define CLAMP(value, low, high) (((value)<(low))?(low):(((value)>(high))?(high):(value)))
War es hilfreich?

Lösung

Ich würde vorschlagen, eine sicherere Art und Weise als ein Makro:

template <typename T> T CLAMP(const T& value, const T& low, const T& high) 
{
  return value < low ? low : (value > high ? high : value); 
}

Andere Tipps

Ihr Makro ist in Ordnung. Wenn Sie in einem high übergeben, die weniger als low ist, werden Sie seltsame Ergebnisse sehen, aber das ist unwahrscheinlich, dass die Ursache sein.

Das wahrscheinlichste Ergebnis ist, dass Sie in einem Ausdruck vorbei sind die Nebenwirkungen, wie zum Beispiel mit dem ++ Operator hat oder eine Funktion aufrufen. Wenn Sie einen Ausdruck haben, die Nebenwirkungen hat, dann wegen der Art und Weise, dass Makroersetzung funktioniert, könnten die Nebenwirkungen mehrfach geschehen. Zum Beispiel:

CLAMP(x++, low, high)  // expands to:
(x++ < low) ? low : ((x++ > high) ? high : x++);

x++ wird mehrfach ausgewertet, das ist definitiv nicht das, was Sie wollen (es ist nicht definiertes Verhalten, aufgrund des Fehlen einer Sequenz Punktes).

Ich würde vorschlagen, das Makro als Vorlage Umschreiben:

template <typename T> T CLAMP(T value, T low, T high)
{
    return (value < low) ? low : ((value > high) ? high : value);
}

eine Template-Funktion verwenden, wie bereits vorgeschlagen, eine bessere Lösung ist.

Wie auch immer, wenn Sie diese Art von Problem sind, die (beide mit einem Makro oder einer Funktion), sollten Sie Ihren Ausdruck vereinfachen; Blick auf diesem Pseudo-Code:

max(a,b): a>b ? a : b
min(a,b): a<b ? a : b
clamp(x,lo,hi): min( hi, max(lo,x) )

Sie können auch eine inline Funktion machen, so dass es wie ein Makro sein wird, aber sicherer.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top