Warum ist dies nicht ein konstanter Ausdruck?
In diesem trivialen Beispiel test2
nicht kompiliert werden, obwohl test1
gelingt, und ich sehe nicht, warum das der Fall ist. Wenn arr[i]
geeignet ist für einen Rückgabewert aus einer Funktion markiert constexpr
kann, warum kann es nicht verwendet werden als non-type template argument?
template<char c>
struct t
{
static const char value = c;
};
template <unsigned N>
constexpr char test1(const char (&arr)[N], unsigned i)
{
return arr[i];
}
template <unsigned N>
constexpr char test2(const char (&arr)[N], unsigned i)
{
return t<arr[i]>::value;
}
int main()
{
char a = test1("Test", 0); //Compiles OK
char b = test2("Test", 0); //error: non-type template argument
//is not a constant expression
}
Edit: Das macht keinen Unterschied:
template<char c>
struct t
{
static const char value = c;
};
template <unsigned N>
constexpr char test1(const char (&arr)[N])
{
return arr[0];
}
template <unsigned N>
constexpr char test2(const char (&arr)[N])
{
return t<arr[0]>::value;
}
int main()
{
char a = test1("Test"); //Compiles OK
char b = test2("Test"); //error: non-type template argument
//is not a constant expression
}
InformationsquelleAutor der Frage Chris_F | 2014-07-04
Du musst angemeldet sein, um einen Kommentar abzugeben.
Kurze Antwort: es gibt keine
constexpr
Parameter der Funktion inC++11/14
.Längere Antwort: in
test1()
wenni
ist nicht eine compile-Zeit-Konstante der Funktion ist noch brauchbar, zur Laufzeit. Aber intest2()
es noch nicht kennt der compiler nicht, obi
ist eine compile-Zeit-Konstanten, und doch, es ist erforderlich für die Funktion zum kompilieren.E. g. den folgenden code für
test1
kompilieren wirdLassen Sie uns einfach Ihre
test2()
zuDiese werden nicht kompiliert, für
test3(0)
denn imtest3()
es nicht bewiesen werden kann, dassi
ist ein bedingungslose compile-Zeit-Ausdruck. Sie müsstenconstexpr
Funktion der Parameter Ausdrücken zu können.Zitat aus dem Standard
5.19 Konstante Ausdrücke [expr.const]
Diesem Abschnitt hat das folgende code-Beispiel entsprechend deiner Frage:
Weil
x
im obigen Beispiel, ist nicht ein konstanter Ausdruck sein, es bedeutet, dass Sie können nicht instanziieren von templates, die entweder mitx
oderk
innenf1
.InformationsquelleAutor der Antwort TemplateRex
Gibt es ein Missverständnis, was
constexpr
nicht hier. Es zeigt an, dass eine Funktion muss evaluatable zur compile-Zeit, für die passenden Argumente, aber es hat nicht entfernen Sie die Anforderung noch zu kompilieren, in den Allgemeinen Fall.Nehmen wir die erste version:
Nun, das ist ganz klar ein compile-time-Auswertung:
Ihrem Beispiel kann werden, aber es ist ein optimizer/QoI Problem:
und diesem Beispiel offensichtlich nicht, aber ist noch erforderlich zu sein evaluatable
Seit
test2
können Sie möglicherweise nicht kompiliert die für den letzten Fall, kann es nicht kompilieren überhaupt. (Bitte beachten ich bin nicht was darauf hindeutet, dass code gute).InformationsquelleAutor der Antwort Useless
Ist hier das problem, dass der Aufruf
arr[i]
erinnert an den subskript-operatoroperator[]
. Dieser operator nicht wieder ein konstanter Ausdruck.Es ist nicht ein problem der
constexpr
eigentlich ein problem von template-argument Abzug. Ein Nicht-Typ template-argument muss ein konstanter Ausdruck, der die Rückkehr argument der subskript-operator nicht.Daher der compiler zu Recht beklagt, dass
arr[i]
ist nicht ein konstanter Ausdruck.InformationsquelleAutor der Antwort 101010
Weil
arr[i]
ist keine Konstante zur Kompilierungszeit Ausdruck. Es kann auch anders laufen-Zeit.InformationsquelleAutor der Antwort user1742529