2012-08-11 3 views
5

Dies ist eine vereinfachte Version, was ich gerne tun würde.Wie kann ich eine temporäre Variable in einer constexpr Funktion haben?

constexpr float f(float a, float b){ 
    constexpr float temp = a+b; 
    return temp*temp*temp; 
} 

In meiner Version, a + b ist etwas viel komplizierter, so dass ich nicht will, und fügen Sie ihn dreimal schneiden. Die Verwendung von 3 * (a + b) ist auch keine funktionierende Lösung für die reale Funktion. Ich versuche, die Frage in Bezug auf Syntax und nicht auf Algebra zu halten. Ich kann es zur Arbeit bringen, indem ich a + b auf seine eigene constexpr-Funktion verschiebe, aber ich würde es vorziehen, den Namensraum nicht mit ansonsten nutzlosen Funktionen zu verschmutzen.

+4

Dies ist die Nummer 1 bei Constexpr. –

Antwort

3

Dies ist in C++ 11 nicht erlaubt, ist aber jetzt in C++ 14 erlaubt.

Siehe https://en.wikipedia.org/wiki/C%2B%2B14#Relaxed_constexpr_restrictions

+2

Sie sollten es anders herum tun. 'f2 (float temp) {Rücklauftemp * temp * temp; } 'und' f (float a, float b) {return f2 (a + b); } '. Auf diese Weise vermeiden Sie die 3 Anrufe. –

+0

Dies ist bei conexpr nicht wichtig, da es dem Compiler anzeigt, dass die Ergebnisse der Funktion zur Kompilierungszeit gespeichert und/oder ausgewertet werden können. Der Compiler wird Temp einmal aufrufen und den Wert 3 mal wiederverwenden. Gesamtsumme von 1 hinzufügen, 3 multipliziert Ihren Weg und meinen Weg. Aber wie ich im Intro gesagt habe, habe ich das Problem vereinfacht, weil es nicht um Algebra geht. –

+2

@JohnK: Es spielt keine Rolle für den kompilierten Code, aber es ist * wichtig für die Menschen, die diesen Code schreiben und lesen. Für den, der es schreibt: Weniger Wiederholung = weniger Gelegenheit, einen Fehler zu machen. Für den, der es liest: Es ist einfacher herauszufinden, dass du dreimal den gleichen Wert hast. – celtschk

6

Wie Sie entdeckt haben, können Sie keine Variablen deklarieren, auch constexpr diejenigen, im Inneren des Körpers eines constexpr Funktion.

Es ist immer noch möglich, einen allgemeinen Ausdruck herauszufiltern, indem Sie ihn als Argument an eine zweite constexpr-Funktion übergeben. Für das hier angegebene Beispiel:

constexpr float pow3(float c) { 
    return c*c*c; 
} 

constexpr float f(float a, float b) { 
    return pow3(a+b); 
}