C++11 – static_assert innerhalb der constexpr-Funktion?

Lesezeit: 3 Minuten

C11 static assert innerhalb der constexpr Funktion
RetroX

Wie würde man richtig a static_assert innerhalb eines constexpr Funktion? Zum Beispiel:

constexpr int do_something(int x)
{
  static_assert(x > 0, "x must be > 0");
  return x + 5;
}

Dies ist kein gültiger C++11-Code, da eine constexpr-Funktion nur eine return-Anweisung enthalten darf. Ich glaube nicht, dass der Standard eine Ausnahme davon hat, obwohl der GCC 4.7 mich diesen Code nicht kompilieren lässt.

C11 static assert innerhalb der constexpr Funktion
Johannes Schaub – litb

Dies ist kein gültiger C++11-Code, da eine constexpr-Funktion nur eine return-Anweisung enthalten darf.

Das ist falsch. static_assert in einem constexpr Funktion sind in Ordnung. Was ist nicht fine verwendet Funktionsparameter in konstanten Ausdrücken, so wie Sie es tun.

Sie könnten werfen, wenn x <= 0. Das Aufrufen der Funktion in einem Kontext, der einen konstanten Ausdruck erfordert, wird dann nicht kompiliert

constexpr int do_something(int x) {
  return x > 0 ? (x + 5) : (throw std::logic_error("x must be > 0"));
}

  • Geil, wusste ich nicht throws in a constexpr Funktion, die in einem constexpr-Kontext aufgerufen wird, führt dazu, dass die Kompilierung fehlschlägt!

    – Xeo

    24. Dezember 2011 um 19:36 Uhr

  • @Xeo tut irgendetwas non-constexpressy auf der anderen Seite von ?: wird den Job machen. 🙂

    – Johannes Schaub – litb

    24. Dezember 2011 um 19:44 Uhr

  • Ich bin verwirrt, warum “Funktionsparameter in konstanten Ausdrücken verwenden” “nicht in Ordnung” ist. Wenn ‘x’ ein konstanter Ausdruck ist, dann ist (x+5) auch ein konstanter Ausdruck und kann zur Kompilierzeit ausgewertet werden. Wenn ‘x’ kein konstanter Ausdruck ist, verliert die Funktion selbst ihre constexpr-ness (für diesen bestimmten Aufruf) und wird einfach zur Laufzeit ausgewertet. Könnte jemand klären?

    – Affe0506

    18. Januar 2013 um 7:53 Uhr


  • @monkey_05_06: Weil ‘x’ ein Funktionsargument ist und daher nicht ein constexpr. Denken Sie daran, dass eine constexpr-Funktion auch als Laufzeitfunktion geeignet sein muss (mit Nicht-constexpr-Argumenten), und daher können ihre Argumente nicht in einer static_assert(…)-Deklaration verwendet werden. Dies ist unabhängig davon, ob Sie die Funktion tatsächlich jemals aus einem Nicht-constexpr-Kontext aufrufen, weshalb die Anforderung, dass eine constexpr-Funktion auch zur Laufzeit aufrufbar sein muss, sowohl eine Einschränkung als auch ein “Feature” darstellt.

    – Äther

    26. April 2013 um 2:15 Uhr


  • @gnzlbg: Siehe seinen Kommentar oben zur Verwendung von etwas, das kein a ist constexpr. Was ich (als generische Lösung) getan habe, war, eine **Nicht-**constexpr-Funktionsvorlage wie folgt zu deklarieren … template<typename RT> RT non_constexpr() { return RT{}; } … so zu verwenden … return (x > 0) ? (x + 5) : non_constexpr<int>(); … getestet in g++ und clang++.

    – Äther

    26. April 2013 um 2:43 Uhr

1646253009 774 C11 static assert innerhalb der constexpr Funktion
cppist

Dies funktioniert und ist gültiger C ++ 11-Code, da Vorlagenargumente nur zur Kompilierzeit gelten:

template <int x>
constexpr int do_something() {
    static_assert(x > 0, "x must be > 0");
    return x + 5;
}

Ich hatte die gleichen Probleme wie Sie mit konstanten Ausdrücken in C++. Derzeit gibt es nur wenige klare Dokumentationen zu constexprs. Und beachten Sie, dass es einige bekannte Fehler im Issue-Tracker von gcc gibt, aber Ihr Problem scheint kein Fehler zu sein.

Beachten Sie, dass Sie, wenn Sie constexpr-Funktionen innerhalb von Klassen deklarieren, diese nicht innerhalb der Klasse verwenden können. Auch das scheint kein Bug zu sein.

Bearbeiten: Dies ist laut Standard erlaubt: 7.1.3 heißt es

… oder eine zusammengesetzte Anweisung, die nur enthält

  • Null-Anweisungen,
  • static_assert-Erklärungen
  • typedef-Deklarationen und Alias-Deklarationen, die dies nicht tun
    Klassen oder Aufzählungen definieren,
  • Verwendungserklärungen,
  • using-Anweisungen,
  • und genau eine return-Anweisung

  • Nein. constexpr darf nur eine einzige return-Anweisung sein.

    – Johan Lundberg

    14. Dezember 2012 um 22:08 Uhr

  • Ich habe die Norm gelesen. Du hast Recht, das ist in Ordnung. Ich habe Ihre Antwort bearbeitet, um das hinzuzufügen.

    – Johan Lundberg

    25. Dezember 2012 um 17:27 Uhr

  • Danke. Dieser Weg funktioniert bei mir sehr gut. Ich kann keine Ausnahmen verwenden, da sie in meinem Build (kleines eingebettetes System) deaktiviert sind.

    – Alexander

    3. Dezember 2014 um 17:19 Uhr

  • Wie nennt man diese Funktion?

    – Sumpf

    3. September 2021 um 2:29 Uhr

915860cookie-checkC++11 – static_assert innerhalb der constexpr-Funktion?

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy