c++ - 智能指针上的模板扣除/替换失败
问题描述
让我们考虑这段代码:
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
}
您可以在此处验证。
这背后的原因是什么?
A
在不修改or的情况下解决此问题的最佳方法是什么B
?
解决方案
这是因为它需要执行自定义转换 from shared_ptr<B>
toshared_ptr<A<int>>
以消除模板函数参数的歧义。模板函数参数的消歧甚至不尝试进行类型转换(除了一些基本的东西)。
甚至尝试都是不切实际的。好吧,理论上可能有一个部分解决方案来指定要尝试的自定义铸件,但没有。只需使用 SFINEA 并自己消除歧义,而不是要求编译器为您完成。
推荐阅读
- node.js - DynamoDB:无法更新节点 js 中的 dynamoDB 项
- java - 将字符串分成 3 部分并在 JAVA 中导出为 CSV
- flutter - 颤振中的JMS(Java消息服务)客户端?
- c# - 我可以将操作应用于 GridView 的 RowDataBound 事件中的一系列单元格索引吗?
- c# - 在多个对象上调用相同的方法
- sql - 如何在 SQL Server 中将行转换为列?
- python - 监控 PI 上的两个 GPIO 引脚
- spring - 为什么在 Spring Boot 2.2.4 中没有加载 restTemplateBuilder?
- c# - 一些 Nunit 测试在组中失败,但在其他环境中单独运行时通过
- angular - “AbstractControl”类型缺少“FormControl”类型的以下属性:registerOnChange、registerOnDisabledChange、_applyFormState