模板扣减替换在智能指针上失败了。

问题描述 投票:0回答:1

让我们考虑一下这段代码。

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
}

你可以验证 此处.

这背后的原因是什么?

有什么办法可以在不修改的情况下解决这个问题?AB?

c++ templates shared-ptr smart-pointers unique-ptr
1个回答
1
投票

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

甚至连尝试都是不切实际的。好吧,理论上本来可以有一个部分的解决方案,指定要尝试哪些自定义的浇铸,但是没有。只需要使用SFINEA,自己去分解,而不是要求编译器为你做。


0
投票

一般来说,如果被调用的函数不改变所有权,你应该避免使用智能指针!使用你的原始指针函数。使用你的原始指针函数。

你强制使用通用类型的 A 按功能 validate. 这里不考虑继承。

如果你忽略继承,它可能看起来像。

template<typename T>
bool validate(std::shared_ptr<T> p)
{
    return true;
}

见上 Godbolt

如果要强制建立一个基类,我会引入一个Typetag。


0
投票

我认为可能的方法有以下几种。

选择1)

  std::shared_ptr<B> pB = std::make_shared<B>();
  //... do your type B related operations through pB
  validate(std::shared_ptr<A<int>>(pB));

替代品2)

template<typename T>
bool validate(A<T> const & a)
{
    //...
    return true;
}

int main()
{
  std::shared_ptr<A<int>> pA = std::make_shared<A<int>>();
  validate(*pA);

  std::shared_ptr<B> pB = std::make_shared<B>();
  validate(*pB);
}

备选方案3)

template<typename T>
bool validate(std::shared_ptr<A<T>> p)
{
    //...
    return true;
}

template<typename T>
bool validate(std::shared_ptr<T> p)
{
    //...
    return true;
}


int main()
{
  std::shared_ptr<A<int>> pA = std::make_shared<A<int>>();
  validate(pA); // it uses bool validate(std::shared_ptr<A<T>> p)

  std::shared_ptr<B> pB = std::make_shared<B>();
  validate(pB); // it uses bool validate(std::shared_ptr<T> p)
}

但这意味着该函数可能会扩展到许多其他类型,而且这不一定是一个理想的行为(也许?

有什么其他的建议吗,伙计们?如果有人知道为什么问题中的代码首先不能工作,那将是很酷的。

© www.soinside.com 2019 - 2024. All rights reserved.