首页 > 解决方案 > 派生类的模板参数推导

问题描述

代码来自https://en.cppreference.com/w/cpp/language/template_argument_deduction,现在我添加 void 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;
}

标签: c++templatestemplate-argument-deduction

解决方案


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

因为它是完全匹配的(当T被推断为时D<int>)。Forf(B<int>*)被称为隐式转换 from D<int>*toB<int>*是必需的。

  1. 我应该进行哪些更改才能拨打f(&d)电话f(B<T>*)

您可以申请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; }

居住


推荐阅读