Im folgenden Codebeispiel if
hängt die Anweisung vom bool
Vorlagenparameter ab, bei dem es sich um eine Konstante zur Kompilierungszeit handelt. Compiler behandeln diesen Code unterschiedlich:
MSVC schlägt mit einem Verbindungsfehler fehl (was ich erwartet habe), da die Vorlagenfunktion in der
else
Verzweigung nicht auf dentrue
Wert der Vorlagenparameter spezialisiert ist (obwohl sie nie aufgerufen wird).GCC und Clang werden beide ohne Probleme kompiliert und das Laufzeitverhalten ist korrekt. Dies liegt offensichtlich daran, dass sie die
if
Anweisung beim Kompilieren auswerten und nicht verwendete Zweige vor dem Verknüpfen entfernen.
Die Frage ist, welches Verhalten standardkonform ist (oder ist es ein undefiniertes Verhalten und beide sind auf ihre Weise korrekt)?
#include <iostream>
template<const bool condition>
struct Struct
{
void print()
{
if (condition)
{
std::cout << "True\n";
}
else
{
printIfFalse();
}
}
private:
void printIfFalse();
};
template <>
void Struct<false>::printIfFalse()
{
std::cout << "False\n";
}
int main()
{
Struct<true> withTrue{};
withTrue.print();
Struct<false> withFalse{};
withFalse.print();
return 0;
}
quelle
if constexpr
Antworten:
Alle Compiler verhalten sich korrekt.
Ihr Programm ist schlecht geformt, es ist keine Diagnose erforderlich , da Sie es
Struct<true>::printIfFalse
durch die Instanziierung desStruct<true>::print()
vom Anruf in erforderlichen Programms verwendenwithTrue.print();
. Eine Funktion, die außerhalb einer verworfenen Anweisung verwendet wird, muss eine Definition im Programm haben, siehe [basic.def.odr] / 4 , andernfalls ist das Programm fehlerhaft , keine Diagnose erforderlich .Eine verworfene Anweisung erhalten Sie, wenn Sie sie
if constexpr
in einer Vorlage verwenden und sich die Anweisung nicht im ausgewählten Zweig befindet. Was Sie also tun können, um das Programm wohlgeformt zu machen, ist, esif constexpr
anstelle von zu verwendenif
. Dies ist eine C ++ 17-Funktion.quelle