Ich glaube, es ist genau das gleiche.
Ich würde nicht sagen, es ist genau das gleiche.
In der ersten Version, können Sie eine bedingte Anweisung verwenden, die zur Laufzeit ausgewertet, aber die Bedingung, dass die (und ist) ausgeführt wird seinen Zweig entscheidet sein kann entschieden zur Compile-Zeit.
Daher müssen beide Zweige kompiliert werden und kompiliert werden, egal was der Typ der Eingabe ist, obwohl wir zur Kompilierzeit wissen, dass nur einer von ihnen ausgeführt wird und der andere wird tot - I erwarte der Compiler würde hier eine Warnung ausgeben.
Im zweiten Fall, Sie kompilieren nur (und ausführen, natürlich) was für die Art des Eingangs geeignet ist. Dies macht meiner Meinung nach den zweiten Ansatz überlegen.
Nun, obwohl es in dieser speziellen Situation wahrscheinlich keinen Unterschied macht, welchen Ansatz Sie wählen, sollten bedingte Ausführungen, die durch Kompilierungsbedingungen entschieden werden, mittels Kompilierzeitkonstrukten ausgedrückt werden - SFINAE und Template-Überladung, während if
sollte für Bedingungen verwendet werden, die vom Laufzeitstatus des Systems abhängen.
Der erste Ansatz wäre zum Beispiel nicht möglich, wenn die beiden Zweige des bedingten enthaltenen Codes nur kompiliert werden, wenn der entsprechende Zweig ausgeführt wird. Betrachten Sie diese zwei Typen:
struct X
{
X(int) { }
};
struct Y
{
Y() { }
};
Und die folgende Funktion Vorlage:
template<typename T>
T foo(const T &a)
{
if (std::is_constructible<T, int>::value)
{
return T(42);
}
else
{
return T();
}
}
Jetzt keine der folgenden Anrufe wäre legal:
foo(X()); // ERROR! X is not default-constructible
foo(Y()); // ERROR! Y is not constructible from an int
Dies allein deutet darauf hin, dass im Allgemeinen, Das geeignete Werkzeug für die bedingte Ausführung der Kompilierungszeit ist das Template-Überladen + SFINAE (oder äquivalente Konstrukte, die möglicherweise involviert sind Ving Klassenvorlagen Spezialisierungen).
Sicher, es gibt degeneriert Fälle (wie diese), die Sie mit anderen Tools, aber wenn wir nach konzeptionell richtigen Design-Richtlinien suchen, glaube ich, gibt es einen klaren Gewinner hier.
Die Dinge würden natürlich anders sein, wenn in C++ so etwas wie static if
existiert, aber das ist im Moment nicht der Fall - und nicht einmal in naher Zukunft, so scheint es.
Ich hätte ersteres bevorzugt, da es in diesem speziellen Fall einfacher zu verstehen ist. Letzteres kann nützlich sein, wenn der Körper der Funktion jedoch komplizierter ist. –