2017-07-28 1 views
1

Ich versuche, einen Funktionsparameter in einer constexpr-if-Anweisung zu vergleichen.Vergleich des constexpr-Funktionsparameters in conexpr-if-Bedingung verursacht Fehler

Hier ist ein einfaches Beispiel:

constexpr bool test_int(const int i) { 
    if constexpr(i == 5) { return true; } 
else { return false; } 
} 

Allerdings, wenn ich kompilieren dies mit GCC 7 mit den folgenden Flags: g++-7 -std=c++1z test.cpp -o test bekomme ich folgende Fehlermeldung:

test.cpp: In function 'constexpr bool test_int(int)': 
test.cpp:3:21: error: 'i' is not a constant expression 
if constexpr(i == 5) { return true; } 

jedoch wenn ich test_int durch eine andere Funktion ersetze:

constexpr bool test_int_no_if(const int i) { return (i == 5); } 

Dann der folgende Code kompiliert ohne Fehler:

int main() { 
    constexpr int i = 5; 
    static_assert(test_int_no_if(i)); 
    return 0; 
} 

Ich verstehe nicht, warum die constexpr-if-Version nicht kompilieren, zumal die static_assert ganz gut funktioniert.

Alle diesbezüglichen Ratschläge wären willkommen.

Danke!

+2

Warum consxpr (i == 5) und nicht nur i == 5? – deW1

+0

any warum so kompliziert? Warum nicht zurück i == 5? – deW1

Antwort

5

Von constexpr if:

In einer constexpr if-Anweisung, muss der Wert der Bedingung sein, ein kontextuell konstanter Ausdruck vom Typ bool konvertiert.

Dann von constant expression:

Definiert einen Ausdruck, der zum Zeitpunkt der Kompilierung ausgewertet werden können.

Offensichtlich ist i == 5 nicht ein konstanter Ausdruck, weil i ein Funktionsparameter, die zur Laufzeit ausgewertet wird. Deshalb beschwert sich der Compiler.

Wenn Sie eine Funktion:

constexpr bool test_int_no_if(const int i) { return (i == 5); } 

dann könnte es während der Kompilierung ausgewertet werden, je nachdem ob es sich um Parameter werden bei der Kompilierung oder nicht bekannt.

Wenn i definiert wie:

constexpr int i = 5; 

dann wird der Wert von i während der Kompilierung bekannt ist und test_int_no_if könnten während der Kompilierung zu machen es möglich, zu nennen es innerhalb static_assert ausgewertet werden.

Beachten Sie auch, dass die Markierung Funktionsparameter wie const es nicht zu einer Kompilierzeitkonstante macht. Es bedeutet nur, dass Sie den Parameter in der Funktion nicht ändern können.

1

Eine constexpr-Funktion kann mit non-constexpr-Argumenten aufgerufen werden. In diesem Fall verhält sie sich wie eine normale Funktion. Der Code muss also so kompiliert werden, als wäre er nicht constexpr.

Kurz gesagt, es gibt nichts in test_int_no_if, das davon abhängt, dass ich constexpr bin, während es in test_int() gibt. ("constexpr if" funktioniert nur mit Kompilierungszeitausdrücken.)

Verwandte Themen