Zeiger als Rückgabewert



  • Hallo alle zusammen,
    ich arbeite aktuell das Buck “C++ - Das umfassende Handbuch“ durch. Hier gibt es im Kapitel Container, Iteratoren, Algorithmen und Hilfsmittel ein etwas retrolastiges Beispiel das mir einfach nicht ganz klar werden will. Hier geht es um eine selbst geschriebene std::find() Funktion die wie folgt aussieht:

    auto find(int* begin, int* end, const int& val) -> int*
    {
    	for (int* it = begin; it != end; ++it)
    	{
    		if (*it == val)
    			return it;
    	}
    	return end;
    }
    

    Mein Verständnisproblem liegt in der Rückgabe von it. Während end ja die Funktion quasi nur durchläuft und entsprechend auch nach der Funktion weiter existiert, ist doch it eigentlich eine lokale Variable und sollte nach dem Funktionsaufruf zerstört werden, oder etwa nicht? Wie kann das Beispiel aber trotzdem funktionieren? Erfolgt hier intern etwas das ich nicht sehe? Sowas wie std::move() vielleicht? Ich wäre euch wirklich dankbar wenn mir da jemand mal auf die Sprünge helfen könnte.

    Beste Grüße und vielen Dank
    pHelloWorld



  • Es wird einfach eine Kopie des Zeigers zurückgegeben, das ist wie return val. Oder return 5.



  • Erstmal vielen Dank für die schnelle Antwort. Das heißt also wenn ich in einer Funktion einen lokalen Zeiger erzeuge der aber nicht auf eine lokale Variable zeigt dann wird das Ganze einfach als call by value zurückgegeben und eine Kopie erstellt. Da hab ich es mir selbst wohl kompliziert gemacht als es ist.



  • Es ist schon wichtig, Pointer und Pointee auseinander zu halten. Natürlich kannst Du aus einer Funktion einen Zeiger zurückgeben. Du solltest nur sicherstellen, dass der auch gültig ist. In Deinem Fall gibt's da keine Probleme. it zeigt auf eines der Objekte, was in dem Feld des Aufrufers liegt. it speichert also die Adresse und die wird einfach zurückgegeben. Ob die Variable it oder sonst wie heißt, oder ob sie "lokal" ist oder nicht, spielt da keine Rolle.



  • Mit anderen Worten: Der Zeiger wird am Leben erhalten, aber zwingend das, worauf er zeigt.
    Ist das lokal in der Funktion, wird es beim Verlassen zerstör.



  • -> int*
    

    Was bedeutet das ?



  • auto func(params) -> return_type 
    {}
    
    template <typename T, typename U>
    auto sum(T a, U b) -> decltype(a+b) // nur so möglich.
    {}
    


  • hu_? schrieb:

    -> int*
    

    Was bedeutet das ?

    Das ist die aktuelle C++11 Rückgabesyntax.

    Danke nochmal an alle für die Antworten. Das hat mir sehr geholfen.


  • Mod

    5cript schrieb:

    template <typename T, typename U>
    auto sum(T a, U b) -> decltype(a+b) // nur so möglich.
    {}
    
    template <typename T, typename U>
    decltype(std::declval<T&>() + std::declval<U&>()) sum(T a, U b)
    {return a+b;}
    


  • pHelloWorld schrieb:

    hu_? schrieb:

    -> int*
    

    Was bedeutet das ?

    Das ist die aktuelle C++11 Rückgabesyntax.

    Echt jetzt ? Nur bei "auto" oder generell ? Stichwort zum Nachlesen ?



  • Mit anderen Worten: Der Zeiger wird am Leben erhalten, aber zwingend das, worauf er zeigt.
    Ist das lokal in der Funktion, wird es beim Verlassen zerstör.
    

    Somit wäre das auch gültig ?

    int* foo(int x){
    
       int* y;
       y = new int[x];
       return y ;
    }
    


  • Ja, das wäre gültig.
    Da du aber rohe besitzende Zeiger verwendest, ist das nicht sonderlich schön.
    Nimm lieber std::unique_ptr.

    @hu_?:
    Nennt sich traling return type:

    T func();
    // wird zu
    auto func() -> T;
    

Log in to reply