Why is decltype deducing rvalue reference for a named value?

82 Views Asked by At

In the following example:

#include <iostream>
 
class A {};

void TestValueCategory(A& ft_) {
    (void)ft_;
    std::cout << "   TestValueCategory(&)...\n";
}   
    
void TestValueCategory(const A& ft_) {
    (void)ft_;
    std::cout << "   TestValueCategory(const &)...\n";
}
    
void TestValueCategory(A&& ft_) {
    (void)ft_;
    std::cout << "   TestValueCategory(&&)...\n"; 
}

template<typename U>
void Forwarder(U&& u_) {
    TestValueCategory(std::forward<U>(u_));
}   
    
auto funcRVOauto() {
    return A();
}
 

int main()
{
    auto&& rv = funcRVOauto();
    std::cout << "\nrv addr [" << (void*)&rv << "]\n";
    std::cout << "rv Value-category is" << (std::is_rvalue_reference<decltype(rv)>::value == true ? "" : " NOT") << " rvalue ref\n";
    Forwarder(rv); //Forwarder(std::move(rv) prints TestValueCategory(&&), as expected
}

Output:

rv addr [0x7fff9434cc6f]
rv Value-category is rvalue ref
   TestValueCategory(&)...

How is decltype able to deduce that the 'original' value category of rv is rvalue reference? Within the context of main, it is a named value after all (e.g. I can take its address), not an x value.

As a follow up, on further reseaerch I found out this same issue has been discussed here:

C++ decltype and parentheses - why?

What is decltype and how is it used?

0

There are 0 best solutions below