允许将派生类的共享指针向量传递给一个函数的正确方法是什么,该函数期望向基类的共享指针向量而不执行副本?
以下是代码:
#include <string>
#include <vector>
#include <memory>
class Base {
public:
std::string Name;
};
using BaseList = std::vector<std::shared_ptr<Base>>;
class Derived : Base {
};
using DerivedList = std::vector<std::shared_ptr<Derived>>;
class BaseHandler {
public:
void process( BaseList list ) {
}
};
int main() {
DerivedList list;
BaseHandler bh;
bh.process( list );
}
编辑:DOH !!!我发错了。很抱歉......这是shared_ptr。
答案 0 :(得分:2)
你可以试试这个。
template <class T,
class SharedPtr = typename T::value_type,
class Element = typename SharedPtr::element_type,
class IsDerived = typename std::enable_if<std::is_base_of<Base, Element>::value, void*>::type
>
void process(const T& t) { std::cout << "process" << std::endl; }
关键的想法是:
跟进:
从&#34;共享指针的容器转换为派生类&#34; to&#34;指向基类的共享指针的容器&#34;是可能的,而不是很困难。但是,我关心的是设计选择使用&#34;容器共享指针到基类&#34;会给你可接受的表现。
让我们先讨论如何做到这一点。
std::shared_ptr<Base>
从每个std::shared_ptr<Derived>
对象创建一个std::static_pointer_cast
对象。std::static_pointer_cast
,我们可以使用std::transform
。所以,代码如下:
DerivedList derivedList;
// Put items into derivedList
BaseList baseList;
baseList.reserve(derivedList.size());
std::transform(std::begin(derivedList), std::end(derivedList), std::back_inserter(baseList),
[](const std::shared_ptr<Derived>& shptr)
{
return std::static_pointer_cast<Base>(shptr);
});
BaseHandler bh;
bh.process(baseList);
或者:
class BaseForwarder
{
public:
template <class T,
class SharedPtr = typename T::value_type,
class Element = typename SharedPtr::element_type,
class IsDerived = typename std::enable_if<std::is_base_of<Base, Element>::value, void*>::type
>
void process(const T& derivedList)
{
BaseList baseList;
baseList.reserve(derivedList.size());
std::transform(std::begin(derivedList), std::end(derivedList), std::back_inserter(baseList),
[](const SharedPtr& shptr)
{
return std::static_pointer_cast<Base>(shptr);
});
BaseHandler bh;
bh.process(baseList);
}
};
然而,这种方法有很多性能损失。
我建议你评估性能,看看这种方法是否可以接受。否则,最好考虑其他一些设计选择。