sah ich ein paar verwandter Stack-Überlauf Fäden wie This case of template function overloading eludes my understandingWarum ist es nicht zulässig, dass nicht vorlagenbasierte Funktionen denselben Namen und dieselben Argumente, aber unterschiedliche Rückgabetypen haben? (Aber legal für Template-Funktionen?)
und
Function overloading by return type?
aber weder scheint mir zu geben genau die Antwort, die ich bin auf der Suche, jedenfalls nicht so, wie ich es leicht interpretieren konnte.
Meine Frage läuft darauf hinaus, diese nach unten: warum, sowohl von einem Design und technischer Sicht ist es legal, dies zu tun:
#include <iostream>
using namespace std;
template<class T>
void func(){
cout << "Compiler inferred from void return value!\n";
}
template<class T>
int func(){
cout << "Compiler inferred from int return value!\n";
return 0;
}
int main(){
void (*thisFunc)()=func<int>;
int (*thatFunc)()=func<int>;
thisFunc();
thatFunc();
}
Aber nicht dieses:
#include <iostream>
using namespace std;
void func(){
cout << "You won't see this because it won't compile!\n";
}
int func(){
cout << "Nor this one!\n";
return 0;
}
int main(){
void (*thisFunc)()=func;
int (*thatFunc)()=func;
thisFunc();
thatFunc();
}
Es ist erwähnenswert Das erste Beispiel wird nicht kompiliert, wenn ich func bei der Initialisierung von thisFunc und thatFunc nicht explizit einen willkürlichen Template-Parameter gebe. Der einzige andere Unterschied zwischen den beiden besteht darin, dass die erste Funktion von einem Typ templiert wurde, der völlig unwesentlich ist, außer dass es mir scheinbar erlaubt, nach Rückgabetyp zu überladen. Der Compiler ist sogar in der Lage, in diesem Fall eine Inferenz zu machen, welche Funktion aufgerufen werden soll, wodurch die Illegalität der Funktionsüberladung durch Rückgabetyp in C++ etwas verwirrend für mich wird. Auf jeden Fall ist es ein netter Trick, denke ich.
EDIT: Die Sache, die mir am meisten ist die Widersprüchlichkeit stört: Ich würde denken, sehr lange und hart, bevor ich wirklich eine Überlastung durch Rückgabetyp in Betracht gezogen, aber wenn die „Fix“ für jemanden, die wollen durch Rückgabetyp zu überlasten Einfach einen bedeutungslosen Template-Parameter hinzufügen oder die Funktionen scheinbar in Namespaces einschließen, dann würde ich denken, dass entweder C++ mehr oder weniger streng sein sollte bezüglich dessen, was es für mehrdeutig hält. Gibt es einen zwingenden Grund, warum Vorlagen und Namespaces diese Funktionalität benötigen, um korrekt zu funktionieren? Gibt es ein Beispiel für einen wünschenswerten Code, der nicht funktionieren könnte, wenn beispielsweise Vorlagen Code nicht wie in meinem Beispiel disambiguieren könnten? Ich frage vom Standpunkt des Sprachdesigns und nicht vom Compiler-Standpunkt.
Für Vorlage, ich denke, es ist erlaubt, SFINAE oder Rückgabetyp. – Jarod42
Sie überlasten den Rückgabetyp nicht wirklich, sondern wählen mit SFINAE die einzige mögliche Template-Instanziierung für jeden Funktionszeiger. Wenn Sie 'func' verwenden, gibt es in jeder Deklaration nur eine Vorlage, in der die Ersetzung funktioniert, aber es ist kein Fehler, dass die andere fehlschlägt. Es wird einfach ignoriert. –