mercredi 28 octobre 2020

Reference collapsing rules not applying as expected?

I am refreshing my memory on how perfect forwarding works in C++. I realize that a call to std::forward is forced to provide an explicit template parameter for a reason (i. e. when dealing with rvalue references that are actually lvalues), however when doing a sanity check on actual code, I was surprised by this (somewhat related) scenario:

#include <iostream>
#include <utility>
#include <type_traits>

template<class T>
T&& fwd(T& t) {
    return static_cast<T&&>(t);
}

template<class T>
T&& fwd(T&& t) {
    return static_cast<T&&>(t);
}

int main()
{
    int lnum = 3;
    if (std::is_rvalue_reference<decltype(fwd(lnum))>::value)
        std::cout << "It's rref." << std::endl;           // this get's printed on screen 
    else
        std::cout << "It's lref." << std::endl;

    return 0;
}

If I understand reference collapsing correctly (and I believe I do), type deduction should go like this:

int& && fwd(int& & t) {                        
    return static_cast<int& &&>(t);         
}

leading to

int& fwd(int& t) {                        
    return static_cast<int&>(t);         
}

Clearly that's not the case. What am I missing here?

Aucun commentaire:

Enregistrer un commentaire