C++11 auto als return type



  • Hallo Community,

    folgendes Beispiel:

    #include <iostream>
    #include <string>
    
    auto fkt()
    {
    	auto s = "hallo welt";
    	return s;
    }
    
    int main()
    {
    	auto s = fkt();
    }
    

    Ich hätte gedacht, dass das funktioniert. Tut es aber nicht. Wieso? Und was ist zu tun, dass es funktioniert?

    Danke im Voraus. 🙂



  • auto schrieb:

    Ich hätte gedacht, dass das funktioniert.

    Warum, wie kommst du auf die Idee?

    Tut es aber nicht. Wieso?

    Warum sollte es? Der Standard schreibt vor, dass ein Rückgabetyp angegeben werden muss.

    Und was ist zu tun, dass es funktioniert?

    Den Rückgabetyp angeben, vielleicht? 🙂



  • pumuckl schrieb:

    auto schrieb:

    Ich hätte gedacht, dass das funktioniert.

    Warum, wie kommst du auf die Idee?

    Weil ich dachte, dass auto dazu da ist, dass sich der Entwickler nicht mehr um Datentypen zu kümmern brauch, da der Compiler sie ja kennt. Ich habe noch ein bisschen gegoogelt und herausgefunden, dass "kennen" hier der springende Punkt ist. Der Compiler kann den Typ (hier std::string) ja gar nicht kennen, da er sich ja nur für die Schnittstelle interessiert und in auto fkt() kommt nirgendwo std::string vor. Damit kann er nicht wissen, ob die Typen bei auto s = fkt() zueinander kompatibel sind. Darum Fehler. Deswegen hat C++11 trailing return type eingeführt, damit das Ganze wieder funktioniert:

    #include <string>
    
    auto fkt() -> std::string // trailing return type
    {
        auto s = "hallo welt";
        return s;
    }
    
    int main()
    {
        auto s = fkt();
    }
    

    Damit muss ich zwar immernoch einen Typ angeben, der Vorteil (finde ich) ist aber, dass die Funktionsnamen untereinander stehen, da auto und void gleich viele Buchstaben haben.



  • Lambdas können den Rückgabetyp herleiten:

    #include <string>
    
    static const auto fkt = []()
    {
        std::string s = "hallo welt";
        return s;
    };
    
    int main()
    {
        auto s = fkt();
    }
    


  • Es ist schon deswegen sinnlos auto als Rückgabetyp anzugeben, weil der Compiler bei der Funktionsdeklaration dann ja die Implementierung kennen müsste. Das bedeutet, dass bei regelmäßiger Benutzung von auto als Rückgabetyp (angenommen, es würde funktionieren) die Compilezeit extrem groß wird. Nichts Wünschenswertes, möchte ich meinen.



  • Eisflamme schrieb:

    Es ist schon deswegen sinnlos auto als Rückgabetyp anzugeben, weil der Compiler bei der Funktionsdeklaration dann ja die Implementierung kennen müsste. Das bedeutet, dass bei regelmäßiger Benutzung von auto als Rückgabetyp (angenommen, es würde funktionieren) die Compilezeit extrem groß wird. Nichts Wünschenswertes, möchte ich meinen.

    Ja, das wäre wohl so. Aber er muss sie doch auch gar nicht kennen. Wie "auto" geschrieben hat, löst der trailing return type das Problem. Der Compiler weiß dann ja wieder, was der Rückgabetyp ist.



  • TyRoXx schrieb:

    Lambdas können den Rückgabetyp herleiten:
    [cpp]
    #include <string>

    static const auto fkt = []()
    {
    std::string s = "hallo welt";
    return s;
    };

    Nö! Das mit dem Herleiten des Rückgabetyps funktioniert nur, wenn der Funktionskörper nur ein return-Statement als einzige Anweisung enthält.



  • krümelkacker schrieb:

    TyRoXx schrieb:

    Lambdas können den Rückgabetyp herleiten:
    [cpp]
    #include <string>

    static const auto fkt = []()
    {
    std::string s = "hallo welt";
    return s;
    };

    Nö! Das mit dem Herleiten des Rückgabetyps funktioniert nur, wenn der Funktionskörper nur ein return-Statement als einzige Anweisung enthält.

    Entweder kann GCC mehr als der Standard verlangt (und Wikipedia lügt) oder du verwechselst das gerade mit constexpr .

    EDIT: Ah, du hast Recht. Diese Lockerung der Regeln ist nur ein Proposal, welches aber schon in GCC implementiert ist (und Clang).



  • auto schrieb:

    (hier std::string)

    Wenn schon wär's wohl eher char const * .



  • Swordfish schrieb:

    auto schrieb:

    (hier std::string)

    Wenn schon wär's wohl eher char const * .

    Und wenn man es ganz genau nimmt, ist "hallo welt" vom Typ const char[]



  • out schrieb:

    Swordfish schrieb:

    auto schrieb:

    (hier std::string)

    Wenn schon wär's wohl eher char const * .

    Und wenn man es ganz genau nimmt, ist "hallo welt" vom Typ const char[]

    const char[11] , oder nicht?



  • Sone schrieb:

    out schrieb:

    Swordfish schrieb:

    auto schrieb:

    (hier std::string)

    Wenn schon wär's wohl eher char const * .

    Und wenn man es ganz genau nimmt, ist "hallo welt" vom Typ const char[]

    const char[11] , oder nicht?

    Genau, jez hommers ganz perfekt.:D



  • out schrieb:

    Sone schrieb:

    const char[11] , oder nicht?

    Genau, jez hommers ganz perfekt.:D

    Nö. Der Rückgabetyp wäre sicher nicht const char[11] sondern müsste entweder tatsächlich zu const char* zerfallen oder implizit in eine Referenz konvertiert werden (sollte man höchstens bei auto& fkt() machen).



  • pumuckl schrieb:

    out schrieb:

    Sone schrieb:

    const char[11] , oder nicht?

    Genau, jez hommers ganz perfekt.:D

    Nö. Der Rückgabetyp wäre sicher nicht const char[11] sondern müsste entweder tatsächlich zu const char* zerfallen oder implizit in eine Referenz konvertiert werden (sollte man höchstens bei auto& fkt() machen).

    Ich zumindest meinte damit eher den Typ des Literals.
    Beim rval haste aber natürlich Recht, da greift das Array-to-Pointer decay.



  • pumuckl schrieb:

    out schrieb:

    Sone schrieb:

    const char[11] , oder nicht?

    Genau, jez hommers ganz perfekt.:D

    Nö. Der Rückgabetyp wäre sicher nicht const char[11] sondern müsste entweder tatsächlich zu const char* zerfallen oder implizit in eine Referenz konvertiert werden (sollte man höchstens bei auto& fkt() machen).

    Ja schon. Sone und ich haben uns aber direkt auf das Zeichenkettenliteral bezogen. Irgendeinem Anfänger hilft das sicher zu einem Aha-Effekt. Viele denken fälschlicherweise, dass ein Zeichenkettenliteral vom Typ const char* ist. Bei der Rückgabe muss natürlich konvertiert werden, da man ja Arrays nicht zurückgeben kann.


Anmelden zum Antworten