Fragwürdige Ausgabe RValue Referenzen Test



  • Kann mir jemand die Ausgabe von diesem Programm erklären?

    #include <type_traits>
    #include <iostream>
    
    template<typename T>
    void f(T&&)
    {
        if constexpr(std::is_same_v<T, int&&>) std::cout << "int&&\n";
        else if constexpr(std::is_same_v<T, int&>) std::cout << "int&\n";
        else if constexpr(std::is_same_v<T, int>) std::cout << "int\n";
    }
    
    int main()
    {
        int a = 0;
        f(0);
        f(a);
        f(std::move(a));
    }
    

    Ausgabe lautet:

    int
    int&
    int
    

    Aber wenn das so wäre, wieso kann ich dann im dritten Fall die Variable a innerhalb von f ändern? Wenn es ein int wäre (so wie im ersten Fall), dann würde ich doch nur die f-lokale Kopie verändern...


  • Mod

    zehenspitze schrieb:

    Kann mir jemand die Ausgabe von diesem Programm erklären?

    #include <type_traits>
    #include <iostream>
    
    template<typename T>
    void f(T&&)
    {
        if constexpr(std::is_same_v<T, int&&>) std::cout << "int&&\n";
        else if constexpr(std::is_same_v<T, int&>) std::cout << "int&\n";
        else if constexpr(std::is_same_v<T, int>) std::cout << "int\n";
    }
    
    int main()
    {
        int a = 0;
        f(0);
        f(a);
        f(std::move(a));
    }
    

    Ausgabe lautet:

    int
    int&
    int
    

    Aber wenn das so wäre, wieso kann ich dann im dritten Fall die Variable a innerhalb von f ändern? Wenn es ein int wäre (so wie im ersten Fall), dann würde ich doch nur die f-lokale Kopie verändern...

    Du testest nur, wie der Templateparameter aussieht. Der Funktionsparameter ist in jedem Fall eine Referenz und lokale Kopien kommen gar nicht vor. Im ersten Fall muss der Aufrufer zwar erst ein temporäres Objekt erzeugen, das gehört aber dem Aufrufer und wird erst am Ende des Ausdrucks, der den Funktionsaufruf enthält, zerstört.



  • Du kannst ja mal T durch T&& in is_same_v ersetzen und gucken, was dann passiert. 🙂


  • Mod

    Du kannst anhand einer forwarding reference nicht zwischen xvalues und prvalues unterscheiden. Du kannst auch mittels overload resolution nicht zwischen ihnen unterscheiden. Nur ad-hoc: decltype((x)) .


Log in to reply