派生类的模板参数推导

时间:2019-09-30 13:10:36

标签: c++ templates template-argument-deduction

代码来自https://en.cppreference.com/w/cpp/language/template_argument_deduction,现在我添加空白f(T*)f(&d)将调用f(T*)

(1)您能解释为什么叫f(T*)吗?

https://en.cppreference.com/w/cpp/language/function_template中 它提到“模板参数推导发生在函数模板名称查找之后(可能涉及依赖于参数的查找)并且在重载解析之前。”

选择f(T *)是因为“过载分辨率”中的“完全匹配”,对吧? 因此,在模板参数推导阶段,选择f(B ),然后在以后的重载解决阶段,选择f(T )并接管f(B *),这是否正确?

谢谢

(2)我应该进行哪些更改以使呼叫f(&d)呼叫f(B<T>*)?我还需要一个f(T*),所以必须保留f(T*)

#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;
}

1 个答案:

答案 0 :(得分:1)

  
      
  1. 您能解释为什么叫f(T*)吗?
  2.   

因为这是完全匹配(当T被推导为D<int>时)。要调用f(B<int>*),需要从D<int>*B<int>*的隐式转换。

  
      
  1. 我应该进行哪些更改才能使呼叫f(&d)呼叫f(B<T>*)
  2.   

您可以申请SFINAE。例如

// 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; }

LIVE