Consider the following example:
template <class T>
void f(const T&&) { std::cout << __PRETTY_FUNCTION__; };
int main(void){
const int *cptr = nullptr;
f(std::move(cptr));
}
Per [temp.deduct.call]/1:
Template argument deduction is done by comparing each function template parameter type (call it
P
) that contains template-parameters that participate in template argument deduction with the type of the corresponding argument of the call (call itA
) [..]
and [temp.deduct.call]/3:
If
P
is a cv-qualified type, the top-level cv-qualifiers of P's type are ignored for type deduction. IfP
is a reference type, the type referred to byP
is used for type deduction.
Considering the given paragraphs, I'm deducing the template argument for T
to be int*
as follows:
P = const T&&, A = const int*; // replacing 'const T&&' with 'const T'
P = const T, A = const int*
T = int*
// what's wrong with these steps?
But when I compile this code with gcc and clang, it shows that the deduced T
is const int*
My Question: Why the deduced template argument is const int*
and not int*
as I expect?
Why the deduced template argument is const int* and not int* as I expect?
The const
in P = const T
is a top level const and applies to T
while the const
in A = const int*
is a low-level const meaning it does not apply to the pointer. This in turn means that you can't directly compare const T
with const int*
the way you have done.
Therefore, T
will be deduced as the simplest argument type const int*
and the function parameter will be of type const int *const &&
.