1

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

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

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

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 类的想法,其中第二个是一个特征类,我可以查询包装对真正初始化函数的调用的函子。在 PodContainer 类中,我可以查询特征类并保存将在那里构造的仿函数,该仿函数将由用户调用并给人一种成员函数的印象。

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

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 :(

4

1 回答 1

0

只要您不能使用 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 ... */
于 2013-01-17T15:14:15.057 回答