Reputation: 586
Stubled upon a weird behaviour when playing with std::forward. Here is a small example:
#include <type_traits>
#include <iostream>
template <typename A>
void func(A&&)
{
std::cout
<< std::is_pointer<A>::value
<< std::is_lvalue_reference<A>::value
<< std::is_rvalue_reference<A>::value
<< std::endl;
using B = typename std::remove_reference<A>::type;
std::cout
<< std::is_pointer<B>::value
<< std::is_lvalue_reference<B>::value
<< std::is_rvalue_reference<B>::value
<< std::endl;
}
int main()
{
int* p = nullptr;
func(p);
}
It prints 010
and 100
, meaning A
is a reference and not a pointer, while std::remove_reference<A>
is a pointer as expected.
But why is it so? I thought that A
would be a pointer and A&&
a reference inside the function body. Also, what types are A&
and A&&
if this is the case?
Upvotes: 2
Views: 64
Reputation: 172934
This is how forwarding reference works; when being passed an lvalue, the template parameter A
will be deduced as an lvalue-reference. For this case, it's int*&
, i.e. an lvalue-reference to pointer. (After reference collapsing, the function parameter's type would be int*&
too.)
When being passed an rvalue, A
will be deduced as non-reference type. For example if you pass an rvalue with type int*
, A
will be deduced as int*
. (Then the function parameter's type would be int*&&
.)
Upvotes: 2