模板类转换问题 - 无法推断调用的函数

Issues with template class conversion - unable to deduce function called

本文关键字:调用 函数 转换 问题      更新时间:2023-10-16

如何使以下代码正常工作?

非模板版本编译完美,但模板版本惨败。为什么模板版本无法确定要调用哪个函数版本以及如何修复它?我想过添加到隐式转换为 BT 的模板类 AT 运算符,但它也不起作用。

class A {};
class B
{
public: 
B(A){};
};
void func(B){};
template<typename T>
class AT {};
template<typename T>
class BT
{
public: 
BT(AT<T>){};
};
template<typename T>
void funcT(BT<T>){};
int main()
{
func(A{});
funcT(AT<int>{}); // unable to deduce the funcT template argument
funcT<int>(AT<int>{}); // compiles but I don't want to write that
return 0;
}

有一些愚蠢的修复,例如编写接受AT<T>并将其转换为BT<T>的函数版本。但是当一切都应该按原样工作时,我不想编写一堆函数。如果这是一个模棱两可的电话,我可以理解它......

模板参数推导中不考虑隐式转换:

类型

推断不考虑隐式转换(上面列出的类型调整除外(:这是重载解决的工作,稍后会发生。

这意味着,对于期望BT<T>但通过了AT<int>funcTT无法推断,并且无法调用。

如您所显示的,解决方法是显式指定模板参数以绕过模板参数推导。

非模板函数没有这样的问题;它们不需要模板参数推导。

另一个答案解释了发生了什么,但有一种方法可以解决这个问题

template<class T, template<class>class Temp, typename std::enable_if<std::is_convertible< Temp<T>, BT<T>>::value, bool>::type = true>
void funcT(Temp<T> t) { 
auto bt = static_cast<BT<T>>(t);
}

这可以由具有相同行为的fooT(A<int>{});调用fooT(B<int>{});调用。