constexpr statisches Mitglied vor / nach C ++ 17

Soweit ich sehen kann, ist eine sehr häufige Situation so etwas wie

template<int i> class Class
{
public:
    static constexpr int I = i;
    static constexpr int J = constexprFunction(i);
    // further Class implementation
};

ast wie üblich sehe ich den Fehler (in der Tat sind die meisten meiner Fragen hier, weil ich es vergessen habe und nicht wusste, was die richtige Frage war), die zusätzliche Definition zu vergessen, wenn das Mitglied odr-used ist:

template<int i> constexpr int Class<i>::I;
template<int i> constexpr int Class<i>::J;

etzt lese ichcppreference: Definitionen und ODR undcppreference: static members, welcher Zustand, dass dies für C ++ 17 veraltet ist. Das scheint mir großartig, weil es viele Fehler vermeidet. Es sind aber noch andere Fragen aufgetaucht:

1) Hat dies andere Gründe, als die zusätzlichen Definitionen unbrauchbar zu machen? (Siehe auch letzten Absatz dieser Frage)

2) Im letzten Beispiel voncppreference: static members es scheint auch auf @ zuzutreffconst static member - aber die Regel gibt nur das @ constexpr member. Wird es auf @ zutreffconst static Mitglied oder nicht?

3) Alle Beispiele, die ich fand, verwendeten eine einfache Definition wieClass::I - Gilt das alles auch für die Situation beiClass:J mitconstexpr Funktionen?

Eine kurze Beschreibung der Best Practices vor C ++ 17 und mit C ++ 17 wäre großartig. Alles in allem scheint mir das eine sehr knifflige Änderung zu sein, da es eine Menge Code, der vorher "falsch geformt, nicht diagnostisch erforderlich" war, zu gutem Code machen wird (soweit ich das verstehe ...). Und infolgedessen wird Code erzeugt, der mit älteren (vor 17) Compilern immer noch "schlecht geformt und nicht diagnostisch erforderlich" ist - aber diese werden sich nicht beschweren, solange keine odr-Verwendung erforderlich ist.

Bearbeite: Der von Aaron McDaid vorgeschlagene Text wurde korrigiert.

Antworten auf die Frage(2)

Ihre Antwort auf die Frage