c++ - 模板推导/替换在智能指针上失败

标签 c++ templates shared-ptr smart-pointers unique-ptr

让我们考虑以下代码:

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

这背后的原因是什么?

在不修改AB的情况下解决此问题的最佳方法是什么?

最佳答案

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

尝试根本不可行。好吧,从理论上讲,本来可以有一个部分解决方案,指定要尝试的自定义强制转换,但没有。只需使用SFINEA即可自己消除歧义,而不是要求编译器为您完成此任务。

关于c++ - 模板推导/替换在智能指针上失败,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61510789/

相关文章:

c++ - 分段故障

c++ - 在编译时复制 C/C++ 函数

c++ - 如果 boost 累加器的类型无效,如何创建回退?

c++ - 函数参数的decltype

c++ - 类的 boost::shared_ptr 作为结构成员

带参数的 JavaScript 和 C++ 回调函数

c++ - 按住键盘输入时犹豫?

c++ - 尝试制作 shared_ptr 时 std::make_shared() 出错?

c++ - 为什么 enable_shared_from_this 有一个非虚拟析构函数?

c++ - 在字符串中输出数据