webentwicklung-frage-antwort-db.com.de

Was ist der Unterschied zwischen statischen Constexpr- und statischen Inline-Variablen in C ++ 17?

Mit C++ 17 erhalten wir Inline-Variablen.

Eine Verwendung für sie besteht darin, konstante Felder in Klassen zu definieren.

Was ist der Unterschied zwischen diesen beiden konstanten Definitionen:

class MyClass {
    static constexpr int myFirstVar = 10;
    static const inline int mySecondVar = 100;
};

Natürlich macht constexprmyFirstVar implizit inline.

Was ist hier die bessere Wahl, um constexpr oder inline zu verwenden?

Hinweis: Wenn Sie keine Konstanz benötigen, macht es inline einfacher. Mit constexpr haben Sie diese Wahl nicht.

47
fen

Sie müssen zum Zeitpunkt der Deklaration keinen Initialisierer für mySecondVar angeben. Es ist auch nicht erforderlich, dass der Initialisierer selbst constexpr ist.

Dies bedeutet, dass, wenn wir versuchen, myFirstVar wie folgt zu definieren:

class MyClass {
    static constexpr int myFirstVar;
};

int MyClass::myFirstVar = 1;

Oder so:

#include <cstdlib>

class MyClass {
    static constexpr int myFirstVar = Rand();
};

Es ist so oder so schlecht geformt. Die Semantik von constexpr verlangt dies aus gutem Grund.

Der inline - Spezifizierer-Ansatz ermöglicht es uns, eine statische Variablendefinition in den Header selbst aufzunehmen, ohne dass der Initialisierer constexpr ist. oder wenn der Initialisierer ziemlich komplex ist, muss er nicht in der Klassendefinition selbst enthalten sein.

Das ist also ein perfekt gültiger Header in C++ 17:

#include <cstdlib>

class MyClass {
    static const int mySecondVar;
};

inline const int MyClass::mySecondVar = Rand();

Der Standard verspricht uns, dass alle Übersetzungseinheiten, die den Header enthalten, denselben Wert für die Variable sehen, auch wenn wir erst zur Laufzeit wissen, was es ist.

Es ist hauptsächlich ein Tool für Bibliotheksautoren. Angenommen, Ihre Bibliothek enthält nur Header. Welche Optionen hatten Sie damals, als Sie eine statische Konstante brauchten, die so definiert war?

Nun, Sie könnten eine Objektdatei mit Ihrer Bibliothek geliefert haben. Es wird aus einer Übersetzungseinheit zusammengestellt, die nur die konstante Definition enthält. Jetzt ist die Bibliothek nicht mehr nur für Header gedacht.

Oder Sie können sich stattdessen auf Inline-Funktionen verlassen. Der Inline-Variable-Effekt kann mit folgenden Mitteln erzielt werden:

class MyClass {
    static inline int mySecondVar();
};

inline int MyClass::mySecondVar() {
  static const int value = Rand();
  return value;
}

Aber es verbirgt sich hinter einer Mauer aus Syntax und verbirgt eine Konstante mit einem Funktionsaufrufoperator.

49
StoryTeller