Wann ist ein constexpr Funktion zur Kompilierzeit ausgewertet?

Da es möglich ist, dass eine Funktion deklariert als constexpr aufgerufen werden können, während der Laufzeit, unter welche Kriterien muss der compiler entscheiden, ob, um zu berechnen, es zur compile-Zeit oder zur Laufzeit?

template<typename base_t, typename expo_t>
constexpr base_t POW(base_t base, expo_t expo)
{
    return (expo != 0 )? base * POW(base, expo -1) : 1;
}

int main(int argc, char** argv)
{
    int i = 0;
    std::cin >> i;

    std::cout << POW(i, 2) << std::endl;
    return 0;
}

In diesem Fall, ich, unbekannt ist zur compile-Zeit, das ist wahrscheinlich der Grund, warum der compiler behandelt POW() als normale Funktion, die aufgerufen wird, zur Laufzeit. Diese Dynamik jedoch, so bequem wie es zu sein scheint, hat etwas unpraktisch Auswirkungen. Zum Beispiel könnte es einen Fall, wo ich möchte, dass der compiler zur Berechnung eines constexpr Funktion während der compile-Zeit, wo der compiler entscheidet, Sie zu behandeln wie eine normale Funktion statt, wenn es funktioniert hätte, während der compile-Zeit als auch? Gibt es bekannte häufige Probleme?

  • AFAIK, wenn alle Argumente Konstante Ausdrücke.
  • Und was ist, wenn ich Schreibe POW((unsigned __int64)2, 63). Würde das trotzdem als ein konstanter Ausdruck?
  • Eigentlich ist es komplexer als das, denke ich. Ich denke constexpr muss nur ausgewertet werden, wenn sein Ergebnis wird als template-parameter, array gebunden ist, oder andere Integrale Konstante. Zu jeder anderen Zeit ist eine Optimierung. In der Tat, auch wenn Sie angesichts konstanter Ausdruck-Argumente, es könnte erforderlich sein, um die Ausführung zur Laufzeit. constexpr int func(int p) { return !p ? 1 : throw std::exception("HI");} muss zur Laufzeit ausgewertet, wenn gegeben, eine nicht-null-Eingabe.
  • Initialisierungen, die Konstante Ausdrücke sind Bestandteil der statischen Initialisierung phase, z.B. constexpr int a = POW(5, 4);. Das ist im wesentlichen berechnet werden bei der Kompilierung. Natürlich können Sie aber auch noch verwenden POW in anderen Orten.
  • Es sei denn, das Ergebnis der Funktion ist in der oben genannten Konstanten Ausdrucks "requirerers", dann gibt es einen compile-Zeit-Fehler, da die Ausnahme.
  • Ich rannte aus der Kommentar-Raum, aber ja 😀
  • Verwandte: stackoverflow.com/questions/14294271/...

InformationsquelleAutor Byzantian | 2013-01-09
Schreibe einen Kommentar