Was ist Erlaubt in einer constexpr-Funktion?
constexpr
- Funktionen sind nicht enthalten soll:
Definition einer Variablen von nicht-wörtliche Art
Aber in diese Antwort ein lambda-Ausdruck definiert ist, in einem: https://stackoverflow.com/a/41616651/2642059
template <typename T>
constexpr auto make_div(const T quot, const T rem)
{
return [&]() {
decltype(std::div(quot, rem)) result;
result.quot = quot;
result.rem = rem;
return result;
}();
}
und in meinem Kommentar, den ich definieren div_t
- in-one: Wie kann ich die Initialisieren eines div_t Objekt?
template <typename T>
constexpr decltype(div(T{}, T{})) make_div(const T quot, const T rem)
{
decltype(div(T{}, T{})) x{};
x.quot = quot;
x.rem = rem;
return x;
}
Genau, was gemeint ist, durch das Verbot der "definition einer Variablen von non-literal type"?
Visual Studio 2015 wird nicht zulassen, dass meine definition von div_t
aber ich finde es unsinnig, es wäre zulässig, nur wickeln Sie solche illegitime Verhalten in einen lambda-Ausdruck und führt ihn aus. Ich würde gerne wissen welche, wenn entweder der Compiler Verhalten sich korrekt in Bezug auf die div_t
definition.
- Welche version der C++ - Sprache? Die Anforderungen waren ganz entspannt ein bisschen aus dem Jahr 2011.
- Gute Frage, ich hab editiert. Aber C++14.
- Ein lambda-Ausdruck ist ein Ausdruck, nicht eine definition. Aber bis C++17, ein lambda-Ausdruck kann nicht in eine konstanter Ausdruck. In der Tat, wenn der Zusammenhang erfordert eine Konstante expression, MSVC wird sich beschweren.
- Also meiner (der ersten) nur als Beispiel kompiliert als constexpr-Funktion ausgewertet wird, da const-Funktion? Meiner Meinung nach das zweite Beispiel sollte nicht kompilieren, per definition.
- Übrigens, wenn Sie nicht versuchen, weisen Sie das Ergebnis der
make_div
zu einemconstexpr
variable Ihre Visual Studio-compiler Fehler Weg geht. Vielleichtmake_div
ist wirklich nichtconstexpr
und der compiler ist, dass wir uns mit ihm Weg erhalten? - Ich glaube nicht, dass VS2015 unterstützt C++14 erweitert
constexpr
. Das erklärt Ihre zweite Funktion Vorlage, da in C++11constexpr
Funktionen sind im Grunde nur eine einzige return-Anweisung; es hat nichts zu tun mit "non-literal type" (unddiv_t
ist ein literal-Typ). Der erste ist schlecht ausgebildet NDR-pre-C++17. - Klingt wie eine brauchbare Antwort zu mir, wenn Sie können unterstützen, dass die Visual Studio 2015 keine Unterstützung für C++14
constexpr
Funktionen. - Ich habe mich vor und verfasst eine Antwort, die Adressen, C++11, C++14 und C++17, also habe ich gelöscht, die Voraussetzung der Frage.
- Das ist toll. Ich dachte, es könnte jemand wollen, tun Sie dies fünf Minuten nach der Entsendung meine lästigen Kommentar...
Du musst angemeldet sein, um einen Kommentar abzugeben.
Es ist praktisch garantiert, wenn es eine Diskrepanz gcc hat das richtige Verhalten, da Visual Studio 2015 unterstützt keine c++14's Erweiterung von
constexpr
: https://msdn.microsoft.com/en-us/library/hh567368.aspx#C-14-Core-Language-FeaturesC++11
constexpr
FunktionenDen Rumpf der Funktion kann nur enthalten:
So c++11 kann nicht dulden, dass die definition von
decltype(div(T{}, T{})) x{}
. Es wäre jedoch akzeptabel, die Rolle der ternären vorgeschlagen hier in einemconstexpr
Funktion die gleichen Ergebnisse zu erzielen:Live Beispiel
C++14
constexpr
FunktionenDen Rumpf der Funktion enthält möglicherweise nichts, aber:
Wo ein "Literal Type" definiert ist hier, speziell für Objekte, obwohl Sie möglicherweise aggregierte Typen mit einer trivialen Destruktor. So
div_t
definitiv qualifiziert. So c++14, und durch die Erweiterung gcc, tolerieren können, ist die definition vondecltype(div(T{}, T{})) x{}
.C++17
constexpr
FunktionenC++17 zusätzliche Unterstützung für die Schließung Typen der definition von "Literal-Typ", deshalb finde ich es seltsam, dass beide gcc und Visual Studio unterstützen die Verwendung der lambda-Ausdruck in der
return
- Anweisung. Ich denke, das ist entweder eine zukunftsgerichtete Unterstützung oder der compiler gewählt, um inline-lambda. In jedem Fall glaube ich nicht, dass Sie qualifiziert sich als eine c++14constexpr
Funktion.[Quelle]