Rückgabewert für "Keine Lösung"
-
Angenommen ich habe eine Funktion, die z.B. die Nullstelle einer Geraden berechnen soll. Wie teile ich dem Aufrufer mit, wenn es keine Lösung geben sollte?
Mir fallen auf Anhieb vier Möglichkeiten ein://Möglichkeit 1: const keine_loesung = INT_MAX; int nullstelle(const Gerade& g) { //... if(keineNullstelle) return keine_loesung; //... return ergebnis; } //Möglichkeit 2: bool nullstelle(cont Gerade& g, int& nullstelle) { //... if(keineNullstelle) return false; nullstelle = ergebnis; return true; } //Möglichkeit 3: class KeineNullstelle { //... } int nullstelle(const Gerade& g) { //... if(keineNullstelle) throw KeineNullstelle(); //... return ergebnis; } //Möglichkeit 4: boost::tuple<int, bool> nullstelle(const Gerade& g) { //... if(keineNullstelle) return boost::tuple<int, bool>(0, false); //... return boost::tuple<int, bool>(ergebnis, true); }Ich denke mal, 1 und 3 kommen nicht in Frage.
Wie würdet ihr es machen?
-
Ich würde es mit bool machen.
In der main funktion kannst ja dann aufrufen mit:if( bool deineFunktion() ) blablaabla; else cout << " Keine Lösung";So auf die Art würde ich es jetzt machen;-)
Aber denke ist auch situatuionsabhängig was das Programm machen soll falls es nicht klappt, bzw falls es klappt.
-
2.) Finde ich am besten. Generell sollte der rückgabewert bei komplizierteren Funktionen stets eine kontrolle sein.
-
Das heißt Möglichkeit zwei?
Irgendwie muss man ja auch die Nullstelle zurückgeben (sofern es eine gibt).
-
Ja, möglichkeit 2. Wenn die Funktion false liefert, dann ist auch der Inhalt von "Nullstelle" nichtssagend und sollte nicht mehr verwendet werden.
-
@JaykopX Danke, meine Frage war an fr33g gerichtet. Du hast ja klar gesagt, welche du vorziehst.
-
Frager schrieb:
Wie würdet ihr es machen?
vector zurückgeben, denn das prog wächst eh und wird bald parabeln und kreise lernen.
-
@volkard: Für Nullstellen wohl die beste Lösung, aber das sollte nur ein Beispiel für eine Funktion sein, die einen "speziellen" Rückgabewert für "keine Lösung" (aber nicht "Fehler") braucht.
-
Frager schrieb:
@JaykopX Danke, meine Frage war an fr33g gerichtet. Du hast ja klar gesagt, welche du vorziehst.
ja ich würde die nullstelle dann als referenz zurückgeben.
so wies ja glaub ich in deinem vorschlag auch ist.
du hast in deiner main funktion eine variable int nullstelle.
so und das ergebnis deiner funktion teilst du dann der nullstelle zu.
da die als referenz übergeben wird, hast du ja damit die nullstelle in deiner main funktion;-)
-
Frager schrieb:
@volkard: Für Nullstellen wohl die beste Lösung, aber das sollte nur ein Beispiel für eine Funktion sein, die einen "speziellen" Rückgabewert für "keine Lösung" (aber nicht "Fehler") braucht.
Allgemein läßt sich keine Aussage machen.
Nehmen wir kleine Objekte, geht meistens pair<bool,Object>, werden sie größer, mut vielleicht bool foo(Object&) sein, Aber was ist, wenn es keine ungültigen Objekte geben kann, dann geht nur Zeiger, aber und und und. Ganz zu vergessen von Überladung mit ungültigen Werten, wie INVALID_HANDLE_VALUE, geschloseenen fstreams, 0 als Zeiger, -1 als Array-Index und so.
-
Ich finde die
bool-Rückgabe gut. Die Anwendung ist recht einfach:int ns; if (nullstelle(gerade, ns)) { // ... }Beim Paar ist es zwar nicht viel komplizierter, ich mag es allerdings, wenn man den Rückgabewert direkt nutzen kann und nicht erst zerlegen muss.
std::pair<bool, int> pair = nullstelle(gerade); if (pair.first) { // ... }Eine Exception würde ich nicht verwenden und auf
INT_MAXabzufragen finde ich auch nicht besonders sinnvoll.
-
Was spricht denn nun dagegen, Nullstellen in einer Liste (oder vergleichbares) zurueckzugeben? Eine leere Liste zeigt an, dass kein Nullstellen existieren. Da sie sowieso weiterverarbeitet werden sollen (z.B. alle NST ausgeben) kann sich die Abfrage des Rueckgabewertes gespart werden und gleich mittels for oder for_each ueber die Liste iteriert werden.
typedef std::list<double> Zeros // oder complex oder float oder ... Zeroes nullstellen() // oder ... void nullstellen(Zeroes& zs)
-
Was spricht denn nun dagegen, Nullstellen in einer Liste (oder vergleichbares) zurueckzugeben?
Nichts. (nur sind die Nullstellen wie gesagt nur ein Beispiel)
Würdest du auch einen Container verwenden, wenn maximal 1 Element zurückgegeben wird?
-
Frager schrieb:
Würdest du auch einen Container verwenden, wenn maximal 1 Element zurückgegeben wird?
Wäre mir mit Standard-Containern zu teuer.
Aber ich muß es mal testen. Einen Container für 0 oder 1 Element habe ich noch rumliegen.
-
Frager schrieb:
Was spricht denn nun dagegen, Nullstellen in einer Liste (oder vergleichbares) zurueckzugeben?
Nichts. (nur sind die Nullstellen wie gesagt nur ein Beispiel)
Würdest du auch einen Container verwenden, wenn maximal 1 Element zurückgegeben wird?In Haskell wird es so gemacht. Zwar gibt es Maybe, aber meist greift man doch auf [] bzw. [a] zurueck.
Aber ich muß es mal testen. Einen Container für 0 oder 1 Element habe ich noch rumliegen.
Naja, es gibt auch Maybe fuer C++, aber da haengt dann aber noch der ganze Monadkram dran.
-
[quote=volkard]Einen Container für 0 oder 1 Element habe ich noch rumliegen.[/quote]
Was ist mit boost::optional?
-
-
Ja, scheint so, als ob optional<T> die boost-Antwort auf Maybe bzw. [a] und [] ist. Leider spare ich mir trotzdem nicht die if-Abfrage.
-
knivil schrieb:
Leider spare ich mir trotzdem nicht die if-Abfrage.
Kann man sich die überhaupt sparen? Denn es muss ja ein anderer Ablaufpfad eingeschlagen werden, abhängig davon, ob die Funktion Nullstellen hat oder nicht. (Ich möchte jetzt nicht auf If-Workarounds wie Funktionszeiger oder sowas hinaus).
-
Ok, das scheint mir für viele Fälle die "schönste" Lösung zu sein. Danke für die Antworten.
