Reputation: 99
The code is from https://en.cppreference.com/w/cpp/language/template_argument_deduction, now I add void f(T*)
, and f(&d)
will call the f(T*)
.
(1) Can you explain why f(T*)
is called?
In https://en.cppreference.com/w/cpp/language/function_template it mentions "Template argument deduction takes place after the function template name lookup (which may involve argument-dependent lookup) and before overload resolution. "
The f(T*) is selected because of the 'Exact match' in 'overload resolution', right? So in template argument deduction phase, the f(B) is selected, then in later overload resolution phase, the f(T) is selected and takes over the f(B*), is this correct?
Thanks
(2) What changes should I make to make the call f(&d)
to call the f(B<T>*)
? I also need the f(T*)
one, so f(T*)
has to be remained.
#include <iostream>
using namespace std;
template<class T> struct B { };
template<class T> struct D : public B<T> { };
template<class T> void f(T*) { cout<< "T*"<< endl; }
template<class T> void f(B<T>*) { cout<< "B<T>*"<< endl; }
int main() {
D<int> d;
f(&d);
return 0;
}
Upvotes: 1
Views: 370
Reputation: 172864
- Can you explain why
f(T*)
is called?
Because it's an exact match (when T
being deduced as D<int>
). For f(B<int>*)
to be called the implicit conversion from D<int>*
to B<int>*
is required.
- What changes should I make to make the call
f(&d)
to call thef(B<T>*)
?
You can apply SFINAE. e.g.
// type trait to get the template parameter from template instantiation
template <typename T>
struct get_template_parameter {
using type = T;
};
template <template <typename> class X, typename T>
struct get_template_parameter<X<T>> {
using type = T;
};
template <typename T>
using get_template_parameter_t = typename get_template_parameter<T>::type;
// only usable when T is B's instantiation or derived class of B's instantiation
template<class T>
std::enable_if_t<!std::is_base_of_v<B<get_template_parameter_t<T>>, T>>
f(T*) { cout<< "T*"<< endl; }
template<class T> void f(B<T>*) { cout<< "B<T>*"<< endl; }
Upvotes: 1