Weisen Sie der Laufzeitvariablen das statische Member consExpr class zu

8

Ich weiß, dass es viele ähnliche Fragen gibt, aber irgendwie andere Fragen. Es handelt sich um folgende Situation:

%Vor%

So weit ich verstehe constexpr steht für Kompilierzeitkonstanten. So kann der Compiler bereits eine Berechnung durchführen, um beispielsweise VALUE zu berechnen. Auch kann ich natürlich ein constexpr std::array<,> definieren, von dem ich die Werte den Laufzeitvariablen zuordnen kann. Ich würde erwarten, dass der Compiler bereits value = 4 in das ausführbare Programm setzt, um eine Ladeoperation zu vermeiden. Ich kann jedoch nicht direkt vom statischen Mitglied zuweisen und erhalte den Fehler

%Vor%

das macht für mich keinen Sinn, weil es mit einem Zwischenschritt einer anderen constexpr Variable gemacht werden kann.

Meine Frage ist also: Warum kann ein statisches conexpr Member einer Klasse keiner Laufzeitvariablen zugewiesen werden?

Hinweis: In meinem MWE ist die Klasse eine Vorlagenklasse, die den Fehler nicht beeinflusst. Jedoch war ich ursprünglich an diesem speziellen Fall interessiert, von dem ich erwarte, dass er allgemeiner ist als für eine Nicht-Template-Klasse.

(Compiler ist clang++ oder g++ mit -std=c++11 - sie geben den gleichen Fehler)

Bearbeiten: @Bryan Chen: Die Ausgabezeilen wurden vergessen. Werden jetzt hinzugefügt.

    
marlam 10.03.2016, 21:41
quelle

2 Antworten

7

Der undefined reference ist ein Linkerfehler. Wenn eine Variable odr-used ist, muss sie eine Definition haben. Dies gilt auch für constexpr Variablen.

Wie bei den meisten ODR-Regeln ist es ein undefiniertes Verhalten, das keine Diagnose erfordert (was erklären könnte, warum Sie für einige Ihrer Verwendungen des Werts keine Diagnose gesehen haben).

Um den Fehler zu beheben, fügen Sie eine Definition außerhalb der Klasse hinzu:

%Vor%

Da es sich um eine Vorlage handelt, können Sie diese in die Kopfzeile einfügen, im Gegensatz zu dem üblichen Fall, in dem die Definition in genau einer .cpp -Datei liegt.

Das Hauptproblem hier ist, ob ARRAY[0] als odr-use zählt. Laut diesem ausführlichen Post , in C ++ 11 und C + +14, das Indizieren eines Arrays zählt als odr-use , aber dies wurde von DR 1926 wurde gegen C ++ 14 eingereicht, um nicht odr-use zu sein.

Allerdings , das heißt über eingebaute Arrays. IDK, ob das gleiche Grundprinzip für std::array gilt, finde ich den Text von [basic.def.odr] / 3 schwer zu verstehen. Gemäß der informellen Definition für cppreference würde std::array::operator[] odr- Verwenden Sie des Arrays, da sein Rückgabewert einen Verweis auf das Array bindet.

    
M.M 11.03.2016, 01:10
quelle
4

Aus diesem Grund gebe ich constexpr-Objekte immer aus einer constexpr-Funktion zurück.

Modifizierter Code unten. Beachten Sie, dass Sie aufgrund eines C ++ 14-Mangels in std::array<> ein const std::array zurückgeben müssen, damit operator[] funktionieren kann.

%Vor%

erwartete Ergebnisse:

%Vor%     
Richard Hodges 10.03.2016 22:06
quelle