min*_*nco 5 c++ boost smart-pointers
我无法解决这个问题.假设我有这个向量
std::vector<std::shared_ptr<Car>> cars;
Run Code Online (Sandbox Code Playgroud)
汽车是一个抽象的类.我希望能够返回不同类型的弱指针,所以我执行以下操作.
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>();
}
Run Code Online (Sandbox Code Playgroud)
当我尝试将该函数与继承自Car的类一起使用时,我收到以下错误.
Error C2440 'initializing': cannot convert from 'std::shared_ptr<Car>' to 'std::weak_ptr<Saab>'
被要求时可能没有有效的汽车.我尝试使用boost :: optional但它不处理多态.如果我不能使用它,我可能会使用原始指针.
你不能直接构造你的weak_ptr<Saab>,shared_ptr<Car>因为模板参数Car必须隐式可转换为Saab才能工作.
但是你可以先将你转换为你的shared_ptr<Car>,shared_ptr<Saab>然后再构建你的weak_ptr.在下面的例子中,我用std::dynamic_pointer_cast它来做.
这是我想出的:
#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();
}
}
Run Code Online (Sandbox Code Playgroud)
打印出来:
萨博
雷诺
Coliru链接:http://coliru.stacked-crooked.com/a/9dbb85b556b83597