Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/templates/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 在C++;_C++_Templates_Void Pointers_Typetraits_Typelist - Fatal编程技术网

C++ 在C++;

C++ 在C++;,c++,templates,void-pointers,typetraits,typelist,C++,Templates,Void Pointers,Typetraits,Typelist,形势 对于类型为T的图像,我有一个模板类TIppImage。我有一个singleton类CIppMemoryManager,它可以存储许多不同大小和类型的图像 class CIppMemoryManager { public: /// ... Singleton interface ... template<class T> TIppImage<T>* GetImage(width, height); private: CIppMemoryManager

形势

对于类型为
T
的图像,我有一个模板类
TIppImage
。我有一个singleton类
CIppMemoryManager
,它可以存储许多不同大小和类型的图像

class CIppMemoryManager
{
public:
  /// ... Singleton interface ... 

  template<class T> TIppImage<T>* GetImage(width, height);

private:
  CIppMemoryManager();
  ~CIppMemoryManager();

  std::map<IppDataType, void*> m_Containers;
};
其中,我使用traits类
TIppTypeTraits
从给定类型获取枚举值

问题

我不能简单地实现像构造函数这样的非模板方法。我需要显式处理所有可能的类型:

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>;
  ...
}
因此,问题是:

a) 是否有某种方法可以遍历不同类型的集合?无法在此处使用traits类,因为函数是非模板的


b) 有没有更好的方法来存储容器集合-不同类型的对象?当它们只是普通模板类的不同专门化时,容器本身非常简单。

我认为boost库中的类变体(
boost::variant
)可能会对您有所帮助。根据变量中存储的类型,可以使用访问者执行适当的代码。
std::vector
可以存储不同类型对象的列表


由于对象相似,它们在内存中的大小可能相同,这是一件好事,因为
boost::variant
存储是基于堆栈的(没有堆分配-这会更快)。

多态
CIppImageContainer
(使它们都共享一个公共基类)和一个智能指针有什么问题


或者某种类型的
boost::variant

boost::variant
是最有可能的候选,但有时
variant
会变得相当大,因为它们需要一些额外的存储空间,还必须处理对齐问题。因此,在某些情况下,
boost::any
可能也有优势:

std::vector<std::pair< Type, boost::any > > data;
std::vector>数据;

轻松地在这样的容器上进行迭代比较困难(
boost::transform\u迭代器不能有多个返回类型,因此如果没有一些模板技巧,这将无法工作)。

boost::mpl::for\u每个
都是为该任务量身定制的。定义一个要操作的类型向量,一个函子或lambda表达式来执行某项操作,您就完成了。

似乎可以解决使用虚拟析构函数进行销毁的问题。只是没有考虑模板类的非模板祖先。但是,<代码> GeMeTime/COD>不能是虚拟的,因为它使用模板参数。它将如何帮助迭代不同类型的集合?考虑一些<代码>变体< /代码>,以及一个结构<代码> MyIsAccess < /Cord>。如果
x
variant
的实例,则
boost::apply_visitor(my_visitor(),x)
将根据变量中存储的类型调用访问者的相应操作符()。现在,如果你有一个
std::vector
,你可以对每个元素使用
apply\u visitor
。老实说,这是难以置信的。关于向量的某些元素,在编译时没有类型信息,因为这是运行时结构。它将如何推断正确的过载?。。或者我应该只看一下
boost::variant
?:)的实现吗是的,这是运行时检测。Variant内部保存一个索引,指示存储的类型。您可以将Apple Yuto访问者视为一个交换机(index),其中每一种情况都调用正确的重载方法。我实际上不打算在这个特殊的问题中使用它,但我认为在其他情况下可以方便地利用它。
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]);
  ...
}
std::vector<std::pair< Type, boost::any > > data;