首页 > 解决方案 > 智能指针上的模板扣除/替换失败

问题描述

让我们考虑这段代码:

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

标签: c++templatesshared-ptrsmart-pointersunique-ptr

解决方案


这是因为它需要执行自定义转换 from shared_ptr<B>toshared_ptr<A<int>>以消除模板函数参数的歧义。模板函数参数的消歧甚至不尝试进行类型转换(除了一些基本的东西)。

甚至尝试都是不切实际的。好吧,理论上可能有一个部分解决方案来指定要尝试的自定义铸件,但没有。只需使用 SFINEA 并自己消除歧义,而不是要求编译器为您完成。


推荐阅读