Funktionen nach Rückgabetyp überladen
-
In C++ kann man Funktionen ja nicht nach ihrem Rückgabetyp überladen, weil der Compiler nicht die gewünschte Funktion bestimmen kann, wenn die Funktionsrückgabe nicht verwendet wird.
Könnte man aber nicht einfach nur für *diesen* Fall einen Compilerfehler erzeugen und andernfalls das Überladen erlauben?
Das wäre z.B.beiint rand(); float rand();
sehr nützlich.
-
das geht leider nicht.
du kannst aber ne template funktion machen:
rand<int>()
und
rand<double>()
-
das geht leider nicht.
Geht nicht, gibt's nicht
Ist C++ und C++ hat Ecken die sind so düster...
Regel:
Zwei Funktionen können in einem Programm koexistieren, wenn sie unterschiedliche Signaturen haben.
Regel:
Für Templatefunktionen gehört der Rückgabewert mit zur Signatur.Folgerung: Zwei Templatefunktionen können koexistieren, selbst wenn sie sich nur im Rückgabetyp unterscheiden:
template <class Dummy> int rand() {...} template <class Dummy> double rand() {...}
Problem: Überladungsauflösung wird niemals eine der beiden Funktionen bevorzugen. Ein Aufruf à la:
int i = rand<bla>();
ist mehrdeutig.
Sowas geht allerdings:
int (*p)() = &rand<bla>; int i = p();
Weiter: Benutzerdefinierte Konvertierungsoperatoren beachten die linke Seite einer Zuweisung. Sowas geht also problemlos:
struct RandCaller { template<class T> operator T() { return T(); } }; int main() { int d = RandCaller(); }
Kombiniere: Verpackt man den Aufruf über den Funktionszeiger in den benutzerdefinierten Umwandlungsop von RandCaller, ist das Problem gelöst:
template <class Dummy> double rand() {return 1.0;} template <class Dummy> int rand() {return 1;} struct RandCaller { template<class T> operator T() { T (*p)() = &rand<int>; return p(); } }; int main() { int i = RandCaller(); double d = RandCaller(); }
Letztes Problem: Ich besitze keinen Compiler der den Code übersetzt.
Ich bin mir zwar recht sicher, dass der Code standardkonform ist und das einmal rand mit Rückgabewert int und einmal mit double aufgerufen wird, nachprüfen kann ich es aber nicht.
Zwar konnte ich den Code mit dem Comeau-Online erfolgreich übersetzen, ausführen geht damit aber ja leider nicht.
-
toll, was nützt das dann wenns im endeffekt sowieso kein compiler kann
-
toll, was nützt das dann wenns im endeffekt sowieso kein compiler kann
Compiler die ich besitze != alle Compiler
Mich wundert allerdings, dass der gcc 3.2 das nicht übersetzt.
-
@HumeSikkins: glaube du hast dich verschrieben
struct RandCaller { template<class T> operator T() { T (*p)() = &rand<int>; // sollte eher '&rand<T>' sein, oder? return p(); } };
-
@zeronull
Nö. Habe mich nich verschrieben. Ist volle absicht. Der Templateparameeter dient ja nur als Dummy. Da könnte auch Foo oder Hugo stehen. Und mir gefiel int am Besten.
-
@HumeSikkins: Alles klar.
-
wie kann das denn gehen? wenn der pointer immer auf die int variante zeigt, wird doch auch immer die aufgerufen, oder was habe ich uebersehen?
-
Der Rückgabewert und das (nicht verwendete) Dummyargument sind unabhängig voneinander.