Durch Markieren einer Funktion als constexpr
wird sie auch zu einer Inline-Funktion. § [dcl.constexpr] / 1:
Eine mit dem constexpr-Bezeichner deklarierte Funktion oder ein statisches Datenelement ist implizit eine Inline-Funktion oder -Variable (7.1.6).
inline
Dies bedeutet wiederum, dass Sie die Definition dieser Funktion in jede Übersetzungseinheit aufnehmen müssen, in der sie verwendet werden kann. Das bedeutet im Grunde, dass constexpr
Funktionen entweder sein müssen:
- beschränkt auf die Verwendung in einer Übersetzungseinheit oder
- in einem Header definiert.
Die meisten typischen Funktionen, die Sie in einem Header deklarieren und in einer Quelldatei definieren möchten (und alle anderen Funktionen, die sie verwenden, enthalten nur den Header und Verknüpfungen mit der Objektdatei dieser Quelle) constexpr
, funktionieren einfach nicht.
Theoretisch könnte man einfach alles in Header verschieben und nur eine Quelldatei haben, die nur alle Header enthält, aber dies würde die Kompilierzeiten drastisch beeinträchtigen und für die meisten ernsthaften Projekte würde das Kompilieren immens viel Speicher erfordern.
Eine constexpr
Funktion ist auch in gewisser Weise eingeschränkt, so dass sie für einige Funktionen möglicherweise überhaupt keine Option darstellt. Die Einschränkungen umfassen:
- virtuelle Funktionen können nicht sein
constexpr
.
- Der Rückgabetyp muss ein "Literaler Typ" sein (z. B. keine Objekte mit nicht trivalisierenden ctors oder dtors).
- Alle Parameter müssen Literal-Typen sein.
- Der Funktionskörper darf keinen
try
Block enthalten .
- Es darf keine Variablendefinition eines nicht-literalen Typs oder irgendetwas mit statischer oder Thread-Speicherdauer enthalten.
Ich habe ein paar ziemlich undurchsichtige Dinge übersprungen (z. B. kann es auch kein goto
oder ein asm
Statement enthalten), aber Sie haben die Idee - für einige Dinge funktioniert es einfach nicht.
Fazit: Ja, es gibt einige Situationen, in denen dies eine schlechte Idee wäre.