[英]Conversion from shared_ptr to weak_ptr polymorphism
I am having trouble getting around this one. 我在解决这一问题时遇到了麻烦。 Let's say I have this vector 假设我有这个向量
std::vector<std::shared_ptr<Car>> cars;
Car is an abstract class. 汽车是一个抽象类。 I want to be able to return weak pointers of different types so I do the following. 我希望能够返回不同类型的弱指针,因此我要执行以下操作。
template<typename T>
std::weak_ptr<T> GetCar()
{
for (std::vector<std::shared_ptr<Car>>::iterator it = cars.begin(); it != cars.end(); ++it)
{
T* derived = dynamic_cast<T*>((*it).get());
if (derived != nullptr)
{
std::weak_ptr<T> carPointer = *it;
return carPointer;
}
}
return std::weak_ptr<T>();
}
I get the following error though when I try to use the function with a class that inherits from Car. 但是,当我尝试将函数与从Car继承的类一起使用时,出现以下错误。 Error C2440 'initializing': cannot convert from 'std::shared_ptr<Car>' to 'std::weak_ptr<Saab>'
There might not be a valid car when asked for it. Error C2440 'initializing': cannot convert from 'std::shared_ptr<Car>' to 'std::weak_ptr<Saab>'
当询问它时,可能没有有效的汽车。 I tried using boost::optional but it does not handle polymorphism . 我尝试使用boost :: optional但它不能处理多态。 I might go with raw pointers if I can't get this to work. 如果我无法使用它,我可能会使用原始指针。
You can't construct directly your weak_ptr<Saab>
from the shared_ptr<Car>
because the template parameter Car
must implicitly be convertible to Saab
in order to work. 您不能直接从shared_ptr<Car>
构造weak_ptr<Saab>
,因为模板参数Car
必须隐式转换为Saab
才能正常工作。
But you can first convert your shared_ptr<Car>
to shared_ptr<Saab>
at first then construct your weak_ptr
afterward. 但是您可以先将您的shared_ptr<Car>
转换为shared_ptr<Saab>
,然后再构造您的weak_ptr
。 In my example below, I used the std::dynamic_pointer_cast
to do it. 在下面的示例中,我使用了std::dynamic_pointer_cast
来执行此操作。
Here is what I came up with : 这是我想出的:
#include <iostream>
#include <vector>
#include <memory>
struct Car
{
virtual void name() = 0;
};
struct Saab : Car
{
virtual void name() { std::cout << "Saab" << std::endl; }
};
struct Renault : Car
{
virtual void name() { std::cout << "Renault" << std::endl; }
};
template<typename T>
std::weak_ptr<T> GetCar(std::vector<std::shared_ptr<Car>> cars)
{
for (std::vector<std::shared_ptr<Car>>::iterator it = cars.begin(); it != cars.end(); ++it)
{
auto derived = std::dynamic_pointer_cast<T>(*it);
if (derived != nullptr)
{
std::weak_ptr<T> carPointer(derived);
return carPointer;
}
}
return std::weak_ptr<T>();
}
int main()
{
std::vector<std::shared_ptr<Car>> cars;
cars.push_back(std::make_shared<Saab>());
cars.push_back(std::make_shared<Renault>());
auto wp = GetCar<Saab>(cars);
auto sp = wp.lock();
if (sp)
{
sp->name();
}
auto wp2 = GetCar<Renault>(cars);
auto sp2 = wp2.lock();
if (sp2)
{
sp2->name();
}
}
It prints out : 它输出:
Saab 萨博
Renault 雷诺
Coliru link : http://coliru.stacked-crooked.com/a/9dbb85b556b83597 Coliru链接: http ://coliru.stacked-crooked.com/a/9dbb85b556b83597
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.