Wann kann ein && Parameter für R-Wert ein L-Wert-Argument bekommen?



  • Hallo Freunde der c++ Programmiersprache.
    Bin dabei im Alleingang mir die Sprache anzueignen. Hauptsächlich über das Buch Prinz c++ lernen.. 6ed. Dann Breymann c++ 5ed sowie lippman c++ 5ed . Verweise in diese Bücher sind sehr willkommen.
    Zu meinen Problem. Ich verstehe vermutlich die Thematik "R-wert && Parameter" nicht korrekt.

    int zahl(4); int && rr = zahl;
    ``` // Error: R-wert-Referenz kann nicht L-Wert übernehmen. OK, für mich Verständlich. breymann5ed . Kap. 11.2 
    
    void ifunk(int && para)  // normale Funktion mit   && Parameter
    // darf nur R-Wert-Argument übergeben. 
    {
    }
    

    Aufruf:

    int i(7); ifunk(i); // für mich Verständlich: Error da L-Wert übergeben.
    

    Was ich nicht verstehe: Das selbe als Funktionstemplate:

    template <class F>
    void templ(F && para)
    {
    	
    }
    

    Aufruf:

    templ(i); // kein Error, WTF
    

    Warum ist die Übergabe des Variablennamens, ein L-Wert, an den && -(Template)-Parameter kein Error???


  • Mod

    Ich mach mal ein paar explizitere Beispiele:

    templ<int>(i);  // Fehler
    templ<int&>(i); // kein Fehler
    templ<int>(4);  // kein Fehler
    templ<int&>(4); // Fehler
    

    Verstanden, was bei dir passiert?
    Wenn du die Variante, wo T zu int& aufgelöst wird, verbieten willst, könntest du sie deleten:

    template<typename T> void templ(T&) = delete;
    

    Oder irgendwas mit type traits basteln, falls du kompliziertere Ansprüche hast.

    Die genauere Erklärung, warum die Sprache sich so verhält wäre vermutlich mehrere Seiten lang. Weiß nicht, ob dich das interessiert. Mit dem Wissen, dass die Sprache sich so verhält, kommt man schließlich auch ganz schön weit.

    PS: Man kann das Spiel übrigens noch eine Ebene weiter treiben:

    templ<int&&>(i);  // Fehler
    templ<int&&>(4);  // kein Fehler
    


  • Wenn ich mich richtig erinnere hat das && bei templates wieder eine eigene Bedeutung und kann quasi alles binden. Scott Meyers nennt das "Universal reference".



  • Ein T && kann, wenn der Typ deduziert wird, eine r-value und eine l-value Referenz binden.

    Wie @DocShoe schrieb, nennt Scott Meyers das Universal Referenz. Wenn Englisch kein Problem darstellt, hier ein Artikel, von eben diesem, der das ganz gut erklärt: https://isocpp.org/blog/2012/11/universal-references-in-c11-scott-meyers


Anmelden zum Antworten