constexpr Variable nicht erfasst
Der folgende Code wird nicht in clang kompiliert (in GCC):
struct A{
int a;
};
auto test(){
constexpr A x{10};
return []{
return x; // <-- here x is A: clang doesn't compile
}();
}
Clangs Fehler ist, dass die Variable 'x' nicht implizit in einem Lambda erfasst werden kann, ohne dass ein Erfassungsstandard angegeben wurde , aber ich dachte, dass constexpr-Variablen immer erfasst wurden.
Wenn x ein int ist, kompiliert der Code:
auto test(){
constexpr int x{10};
return []{
return x; // <-- here x is int: clang is ok
}();
}
Interessanterweise wird auch der folgende Code kompiliert:
auto test(){
constexpr A x{10};
return []{
return x.a;
}();
}
Ist Klirren richtig? Wenn ja, was ist die Begründung? Ich benutze -std = c ++ 17
--BEARBEITEN--
Die folgende Frage: Kann ich einen constexpr-Wert in einem Lambda verwenden, ohne ihn zu erfassen? ist nicht mit diesem verwandt, wie bei clang11 ist es kein Problem mehr: Wie oben angegeben, kompiliert clang11, wie oben angegeben, wenn x ein int ist.
Beispielcode auch vorhanden in https://godbolt.org/z/rxcYjz
Antworten
Wenn Sie return x;
im ersten Beispiel den A
Kopierkonstruktor aufrufen, müssen Sie einen Verweis darauf binden x
und ihn daher von odr verwenden. Es kann argumentiert werden, dass eine triviale Kopie eines Werts, der in konstanten Ausdrücken verwendet werden kann, nicht mehr als eine odr-Verwendung darstellen sollte return x.a;
, aber es gibt keine solche Ausnahme in dieser Regel, so dass Clang es richtig ist , sie abzulehnen.
In der Praxis können Sie natürlich jede constexpr
Variable festlegen static
, um zu vermeiden, dass sie erfasst werden muss.