如何为带有函子的自定义容器创建泛型插入函数

How to create a generic insert function for a custom container with a functor

本文关键字:创建 泛型 函数 插入 自定义      更新时间:2023-10-16

在这一点上,我不担心这是我的问题的正确解决方案(事实上,它不是),但我遇到了这个问题,我不能解决它,所以它一直困扰着我,我不能放手。

我有一个POD类型的通用容器。这个容器可以通过不初始化内存和出于性能原因不调用任何构造函数或析构函数来避免复制,作为交换,用户对此负责(对于pods和我们的用例来说,这不是什么大问题)。

这是一个关于如何使用这个的非常简单的演示。

template <typename Pod_Type>
class PodContainer
{
public:
   //stl-like iterators for compatibility with stl-algorithms
   Pod_Type* begin();
   Pod_Type* end();
   //special "insertion" function that inserts a non-initialized pod
   Pod_Type* new_empty();
   //This "something" is my problem. I guess this has to be a functor. 
   //More on this later
   Something generic_insert;
private:
    Pod_Type* mStorage; //Allocated space for pods
};
//Simple structure to use as example
struct PodA
{
   int x,y,z;
};
//Function to initialize a pod of type podA with the given params
inline
init_podA( podA* ptr, int a, int b, int c) 
{
   ptr->x = a; ptr->y = b; ptr->z = c;
}

int main()
{
  //Create a buffer
  PodContainer<podA> buff;
  //Insert some elements and intialize them "by hand"
  for (int i=0; i < 10 ; ++i)
  {
     init_podA( buff.new_empty(), 1,2,3);
  }
}

请注意,容器类的所有内存管理问题都解决了(我已经对它进行了广泛的测试),容器本身非常适合我的实际问题。

现在是有趣的部分。我想让这个"东西"在容器内从调用我的init_podA函数。显然,我不能在Buffer类中硬连接这一点,因为我甚至不知道用户将需要为其pod类型的下一个init_xxx函数需要多少参数。我开始考虑将第二个参数模板传递给PodContainer类,其中第二个参数模板是一个trait类,我可以查询包含对实际初始化函数调用的函子。在PodContainer类中,我可以查询traits类并保存将在那里构造的函子,它将由用户调用,并给人一种成员函数的印象。

我的想法是这样使用这些特征:

template<typename PodType, typename PodTraits = MyPodTraits<PodType> >
class PodContainer
{
 PodContainer():
      generic_insert(PodTraits::get_inserter(this))
 //The rest of the PodContainer definition
 ....    
//And the user of the container would see this
PodContainer<PodA> buffer;
buffer.generic_insert(a,b,c); //Calls buffer->new_empty and initializes a pod

这可能吗?我想我会使用一些boost::bind欺骗,我是对的吗?函子的类型是什么,所以我可以在容器中接收它?有没有更好的选择?

谢谢! !

编辑:注意我不能使用c++11:(

只要您不能使用c++ 11(和可变模板),您总是可以采取艰难的方式,为每个可能数量的参数提供重载。像这样:

void generic_insert(void (*init)(PodType*)) { init(new_empty()); }
template<typename A1>
void generic_insert(void (*init)(PodType*, A1), A1 a1) { init(new_empty(), a1); }
/* and so on ... */