Designfrage: Mehrere Variablen zurückgeben



  • Ich möchte mal wissen, was guter Stil ist, wenn man mehrere Variablen zurückgeben möchte:

    Überschreibt ihr die Variablen per Ref?
    Macht ihr dafür eine eigene Struct/Klasse?
    Setzt ihr alles in ein Array?
    ... oder ganz was anderes?

    Da ich auch in einem sauberen Stil schreiben möchte, würde mich interessieren, wie ihr das angeht. Gibts da eine Regel für oder ist das nur Geschmackssache?

    Vielen Dank! 🙂



  • Kommt drauf an, und zwar auf Anzahl, Komplexitaet, Interface, Caching, ...



  • Die sauberste Variante ist mMn. nen Struct zurückzugeben.
    Je nachdem was man zurückgibt sind auch Output-Parameter (Referenz) OK.

    Und ganz ganz selten bietet sich mal std::pair bzw. tuble an. Mach ich aber echt nur wenn ganz klar was first und second bedeutet. Also wenn z.B. ich ne Iterator-Range zurückgebe ( first = begin, second = end). Sonst lieber ne eigene Struct. Dann haben die Dinger nen Namen, und es kommt zu keinen weniger Misverständnissen (bzw. man ist allgemein beim Lesen schneller).

    ps: Wenn Performance ne Rolle spielt, dann stellt sich die Frage danach was "sauber" ist mMn. nicht mehr. Dann ist eher die Frage was weniger unsauber ist. Meine Antwort bezieht sich auf Fälle wo Performance weniger ein Thema ist.



  • Sowohl wenn man mehrere Werte zurück gibt, als auch übergibt, eignet sich dafür ein Struct.



  • Sollte es sich um mehrer, logisch nicht eng zusammengehörende Werte handeln, ist die Kombination aus std::tuple und std::tie auch nicht so übel.



  • Lymogry schrieb:

    Ich möchte mal wissen, was guter Stil ist, wenn man mehrere Variablen zurückgeben möchte:

    IMHO ist es guter Stil, wenn eine solche Situation gar nicht erst auftritt - Ok - es gibt immer Ausnahmen 😉

    Lymogry schrieb:

    Überschreibt ihr die Variablen per Ref?

    wäre eine Möglichkeit, wenn es wenige sind warum nicht.

    Lymogry schrieb:

    Macht ihr dafür eine eigene Struct/Klasse?

    Das ist die Frage: warum sind sie nicht schon in einer eigenen Struct/Class zusammen gefasst? Das lässt sich aber pauschal kaum beantworten.

    Was sind das für Variablen und was macht die Funktion, die sie zurück gibt? Wie stark ist die Kohäsion zwischen den Variablen? Lassen sich die einzelnen Variablen auch von einzelnen Funktionen/Algorithmen bestimmen? Macht es Sinn die Funktion als Methode einer Klasse schreiben und die Variablen wären dann Member dieser Klasse? Sind alle Variablen von gleichem Typ - wäre eine Container oder Output-Iterator sinnvoll?

    Ich denke, es ist einfacher zu diskutieren, wenn Du konkreter wirst und uns ein konkretes Beispiel vorlegst.

    Gruß
    Werner



  • Da gibt es nichts Konkretes. Ich machs mal so, mal so. Aber bisher musste nur ich damit klar kommen.

    Wenn mehrere Leute an einem Programm arbeiten, sollte es aber übersichtlich bleiben.
    Also stößt euch da nichts wirklich auf...

    Schonmal Danke für die Antworten!



  • Gib ein tuple zurueck und benutz dann pattern matching:

    foo :: Int -> (Int, Int)
    foo a = (a+1, a+2)
    
    main :: IO ()
    main = do
      let (x,y) = foo 1
      print x
      print y
    

    http://codepad.org/qNaIAI6T

    PS: Oh, sorry, falsches Forum. Ja ok, in einer so behinderten Sprache wie C++ gehen nur nervtötende Dinge wie std::pair, struct, call by ref usw.



  • tuple pattern matching schrieb:

    PS: Oh, sorry, falsches Forum.

    Kann ja mal passieren. FTFY

    #include <tuple>
    #include <iostream>
    
    int main(){
      auto foo = [](int i){ return std::make_tuple(i+1, i+2); };
      int x, y;
      std::tie(x,y)=foo(1);
      std::cout << x << ' ' << y << '\n';
    }
    


  • Oh, tie ist ja nett. Das kannte ich noch gar nicht. Ist zwar immernoch etwas mehr visual noise, aber schon viel besser. Danke für den Hinweis. 🙂


Anmelden zum Antworten