让我们考虑以下代码:
template<typename T>
struct A
{
//...
};
struct B : public A<int>
{
//...
};
template<typename T>
bool validate(A<T>* p)
{
//...
return true;
};
int main()
{
A<int>* pA;
std::cout << validate(pA) << std::endl;
B* pB;
std::cout << validate(pB) << std::endl;
}
它可以正确编译并按预期工作。现在,假设我需要重构代码以使用智能指针,然后可以像这样更改
validate
:template<typename T>
bool validate(std::shared_ptr<A<T>> p)
{
//...
return true;
};
int main()
{
std::shared_ptr<A<int>> pA = std::make_shared<A<int>>();
validate(pA); //it compiles correctly
std::shared_ptr<B> pB = std::make_shared<B>();
validate(pB); //it FAILS to compile
}
您可以验证here。
这背后的原因是什么?
在不修改
A
或B
的情况下解决此问题的最佳方法是什么?
最佳答案
这是因为它需要执行从shared_ptr<B>
到shared_ptr<A<int>>
的自定义转换,以消除模板函数参数的歧义。消除模板函数参数的歧义甚至不会尝试进行类型转换(除了一些基本的东西)。
尝试根本不可行。好吧,从理论上讲,本来可以有一个部分解决方案,指定要尝试的自定义强制转换,但没有。只需使用SFINEA即可自己消除歧义,而不是要求编译器为您完成此任务。
关于c++ - 模板推导/替换在智能指针上失败,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61510789/