c++ - 派生类的模板参数推导
问题描述
代码来自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;
}
解决方案
- 能解释一下为什么
f(T*)
叫吗?
因为它是完全匹配的(当T
被推断为时D<int>
)。Forf(B<int>*)
被称为隐式转换 from D<int>*
toB<int>*
是必需的。
- 我应该进行哪些更改才能拨打
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; }
推荐阅读
- eclipse - Eclipse EditorPart 保存在 partDeactivated 上
- c# - Recurring Job异步调用WebApi,然后在回调方法中修改Hangfire Job的状态
- javascript - Nuxtjs 结合 spa 预渲染
- c++ - 在 Qt 中显示对话框的密码
- spring-boot - 在 Angular 6 中停止 addEventListener
- sql - 将 JSON 字符串转换为十进制的问题
- postgresql - 在 postgresql 执行语句中使用变量
- spring - 客户端发现后 Eureka Server 停止工作
- java - 在 Spring Boot 应用程序中配置 Jackson mixin
- python - 再次使用密钥列表从列表中创建字典