This example on the usage of std::forward is puzzling me. This is my edited version:
#include <iostream>
#include <memory>
#include <utility>
using namespace std;
struct A{
    A(int&& n) { cout << "rvalue overload, n=" << n << "\n"; }
    A(int& n)  { cout << "lvalue overload, n=" << n << "\n"; }
};
template<typename> void template_type_dumper();
template<class T, class U>
unique_ptr<T> make_unique(U&& u){
    //Have a "fingerprint" of what function is being called
    static int dummyvar;
    cout<<"address of make_unique::dummyvar: "<<&dummyvar<<endl;
    //g++ dumps two warnings here, which reveal what exact type is passed as template parameter
    template_type_dumper<decltype(u)>;
    template_type_dumper<U>;
    return unique_ptr<T>(new T(forward<U>(u)));
}
int main()
{
    unique_ptr<A> p1 = make_unique<A>(2); // rvalue
    int i = 1;
    unique_ptr<A> p2 = make_unique<A>(i); // lvalue
}
The output is
address of make_unique::dummyvar: 0x6021a4
rvalue overload, n=2
address of make_unique::dummyvar: 0x6021a8
lvalue overload, n=1
and the warnings about reference to template_type_dumper show that in the first instantiation, decltype(u) = int&& and U = int, for the second decltype(u) = int& and U = int&.
It's evident that there are two different instantiations as expected, but her are my questions:
- how can std::forwardwork here? In the first instantiation, its template argument is explicitlyU = int, how can it know that it has to return a rvalue-reference? What would happen if I specifiedU&&instead?
- make_uniqueis declared to take a rvalue-reference. How come- ucan be a lvalue-reference? Is there any special rule that I am missing?
 
    