C++ check if-Anweisung kann constexpr ausgewertet werden
Lesezeit: 5 Minuten
Aart Stuurmann
Gibt es eine Methode, um zu entscheiden, ob etwas constexpr ausgewertet werden kann, und das Ergebnis als constexpr boolean zu verwenden? Mein vereinfachter Anwendungsfall ist wie folgt:
@AartStuurman: Was ist do_stuff dass es zur Kompilierungs- oder Laufzeit ausgeführt werden kann, aber selbst nicht ausgeführt werden sollte constexpr? Wäre es nicht sinnvoller, es einfach zu machen constexpr Funktion, und übergeben Sie ihr den Wert von get_data als Parameter?
– Nicol Bolas
21. März 2019 um 20:38 Uhr
cpplerner
Hier ist eine andere Lösung, die allgemeiner ist (anwendbar auf jeden Ausdruck, ohne jedes Mal eine separate Vorlage zu definieren).
Diese Lösung nutzt, dass (1) Lambda-Ausdrücke ab C++17 constexpr sein können (2) der Typ eines erfassungslosen Lambda ab C++20 standardmäßig konstruierbar ist.
Die Idee ist, die Überlastung, die zurückkehrt true wird ausgewählt wann und nur wann Lambda{}() kann innerhalb eines Vorlagenarguments erscheinen, was effektiv erfordert, dass der Lambda-Aufruf ein konstanter Ausdruck ist.
Faszinierende Lösung … auf diese Weise erhalten Sie das gleiche Ergebnis meiner benutzerdefinierten Typmerkmale, aber synthetischer und vor allem den genauen verifizierten Ausdruck (base::get_data()) ist in das Argument eingebettet und nicht wie in meiner Lösung fest codiert. Sehr schön. Ich muss es mir merken.
– max66
22. März 2019 um 0:24 Uhr
Ich akzeptiere dies, weil es eine Antwort auf den allgemeinen Fall der Frage ist. max66-Antwort ist auch sehr nützlich (in Nicht-C ++ 2a-Fällen), erfordert jedoch eine Wiederholung für jede Verwendung 🙂
– Aart Stuurmann
22. März 2019 um 9:42 Uhr
Komma-Operator SFINAE … mein Verstand macht BOOM.
– Biomann
24. Oktober 2021 um 8:02 Uhr
Eine erhellende Lösung des Problems. Ich habe diesbezüglich einige Tests durchgeführt, und ich glaube, dass die Verwendung des Kommas SFINAE unnötig ist, und ich bin mir ziemlich sicher, dass eine Vorlage des Formulars vorhanden ist template<typename T, auto = T()() >wo meine T ist dein Lambda würde auch reichen.
– Benutzer2628206
17. Januar um 7:17 Uhr
Bei näherer Betrachtung wird das Komma SFINE aufgrund des void-Rückgabetyps von Lambda benötigt. (In meinen Tests habe ich ein Lambda verwendet, das verwandt ist mit []{ base::get_data(); return true;}die immer nicht leer ist.
– Benutzer2628206
17. Januar um 19:24 Uhr
max66
Nicht genau das, was Sie gefragt haben (ich habe ein benutzerdefiniertes Typmerkmal speziell für a entwickelt get_value() statische Methode … vielleicht ist es möglich, es zu verallgemeinern, aber im Moment weiß ich nicht wie), aber ich nehme an, Sie können SFINAE verwenden und etwas wie folgt machen
Hmm, der Körper von a
if constexpr
wird nur ausgewertet, wenn der Ausdruck in derif constexpr
ist zur Kompilierzeit wahr. Ist es das, was Sie suchen?– Jesper Juhl
21. März 2019 um 20:13 Uhr
Aber was ist, wenn der Test in if constexpr([test]) ist zur Kompilierzeit nicht auswertbar?
– Aart Stuurmann
21. März 2019 um 20:17 Uhr
Vielleicht kannst du etwas damit anfangen
std::is_constant_evaluated
?– 0x5453
21. März 2019 um 20:18 Uhr
de.cppreference.com/w/cpp/language/if
– Jesper Juhl
21. März 2019 um 20:18 Uhr
@AartStuurman: Was ist
do_stuff
dass es zur Kompilierungs- oder Laufzeit ausgeführt werden kann, aber selbst nicht ausgeführt werden sollteconstexpr
? Wäre es nicht sinnvoller, es einfach zu machenconstexpr
Funktion, und übergeben Sie ihr den Wert vonget_data
als Parameter?– Nicol Bolas
21. März 2019 um 20:38 Uhr