场合
对于TIppImage<T>
类型的图片,我有一个模板类T
。我有单件类CIppMemoryManager
,它可以存储大量不同大小和类型的图像。
class CIppMemoryManager
{
public:
/// ... Singleton interface ...
template<class T> TIppImage<T>* GetImage(width, height);
private:
CIppMemoryManager();
~CIppMemoryManager();
std::map<IppDataType, void*> m_Containers;
};
IppDataType
是枚举,其值对应于实际类型。所有管理都在模板类TIppImageContainer<T>
中完成。此类的所有专精都存储在m_Containers
中void*
。它不是很好,但它至少是简单的。
通过这种方法,我可以简单地实现模板GetImage
方法:
template<class T> TIppImage<T>* CIppMemoryManager::GetImage(width, height)
{
return reinterpret_cast<TIppImageContainer<T>*>(m_Containers[
TIppTypeTraits<T>::ipp_data_type])->GetImage(width, height);
}
我正在使用traits类TIppTypeTraits<T>
来获取给定类型的枚举值。
问题
我不能简单地实现非模板方法,比如构造函数。我需要明确处理所有可能的类型:
CIppMemoryManager::CIppMemoryManager()
{
m_Containers[ipp8u] = new CIppImageContainer<Ipp8u>;
m_Containers[ipp8s] = new CIppImageContainer<Ipp8s>;
m_Containers[ipp16u] = new CIppImageContainer<Ipp16u>;
m_Containers[ipp16s] = new CIppImageContainer<Ipp16s>;
...
}
更糟糕的是,对于析构函数我还需要处理void*
:
CIppMemoryManager::~CIppMemoryManager()
{
delete reinterpret_cast<TIppImageContainer<Ipp8u>*>(m_Containers[ipp8u]);
delete reinterpret_cast<TIppImageContainer<Ipp8s>*>(m_Containers[ipp8s]);
delete reinterpret_cast<TIppImageContainer<Ipp16u>*>(m_Containers[ipp16u]);
delete reinterpret_cast<TIppImageContainer<Ipp16s>*>(m_Containers[ipp16s]);
...
}
所以,问题是:
a)有没有办法迭代不同类型的集合?因为函数是非模板,所以不能在这里使用traits类。
b)是否有更好的方法来存储容器集合 - 不同类型的对象?当它们只是普通模板类的不同专业化时,容器本身就非常简单。
答案 0 :(得分:2)
我认为来自boost库(boost::variant
)的类变体可能会对您有所帮助。您可以使用访问者根据变体中存储的类型执行相应的代码。 std::vector<boost::variant<T0, T1,...>>
可以存储不同类型的对象列表。
由于您的对象相似,它们在内存中的大小可能相同,这是一件好事,因为boost::variant
存储是基于堆栈的(没有堆分配 - 这样更快)。
答案 1 :(得分:1)
多态CIppImageContainer<T>
(让它们共享一个共同的基类)和智能指针有什么问题?
或某种boost::variant
?
答案 2 :(得分:1)
boost::mpl::for_each
是为这项工作量身定做的。定义要操作的类型向量,函子或lambda表达式来做某事,你就完成了。
答案 3 :(得分:0)
boost::variant
是最有可能的候选人,但有时variant
S变得相当大,因为他们需要一些额外的存储并且还必须处理对齐。所以也许boost::any
在某些情况下也有优势:
std::vector<std::pair< Type, boost::any > > data;
要轻松地迭代这样的容器更难(boost::transform_iterator
不能有多个返回类型,所以如果没有一些模板技巧,这将无法工作。)