template<typename T>
void func(T&);
int x=0;
func(x); // OK, int&
const int cx=0;
func(cx); // OK, const int&
func(0); // invalid initialization of non-const reference of type 'int&' from an rvalue of type 'int'
But why doesn't the 'const int&' type get deduced in the third case? What is the rationale behind this type deduction rule?
After all, we can perfectly bind a number to const lvalue reference.
It's because the type of 0
is int
, not const int
. (There are no cv-qualified prvalues of scalar type.) Since the deduction only takes into account the type, and not the value category, T
must be deduced as int
here just as it was in the case of x
--- even though that results in an attempt to perform an invalid reference binding.
(A forwarding reference T&&
has special rules that take into account the argument's value category when deducing T
. So passing in x
and passing in 0
would deduce T
differently. But for an ordinary reference T&
, only the argument's type matters.)
I find it easier to imagine whats going wrong here if you understand that a reference is just a pointer with syntax. So if your method was:
template<typename T>
void func(T*);
int x=0;
func(&x); // OK, you can take the address of x
const int cx=0;
func(&cx); // OK, you can take the address of cx
func(&0); // Taking the address of 0 doesn't make sense.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.