【问题标题】:How to create a generic insert function for a custom container with a functor如何使用仿函数为自定义容器创建通用插入函数
【发布时间】:2013-01-17 14:34:35
【问题描述】:

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

我有一个用于 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);
  }
}

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

现在是有趣的部分。我想让这个“东西”从容器 inside 调用我的 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 :(

【问题讨论】:

  • 我认为这里可能有些混乱。首先,像init_podA 这样的初始化函数有什么意义?您确实意识到,如果您只给 podA 一个构造函数,编译器本质上会生成完全相同的东西,是吗?
  • 你想实现类似 STL 的emplace_back() 功能吗?
  • 差不多。我已经看到过类似的东西(来自folly's FBVector),但我暂时不能使用c++11 :(。可能应该在问题中添加限制。
  • @slavik262 这来自于逃避 STL 设计并在处理这些 pod 的批次时避免使用复制构造函数。无论如何,相信我,这不是问题的中心点,这主要是对如何做另一部分的好奇。
  • 您要做什么标准容器无法做到的事情(有很多,选择一个!)?

标签: c++ c++03


【解决方案1】:

只要您不能使用 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 ... */

【讨论】:

    猜你喜欢
    • 2017-08-01
    • 1970-01-01
    • 1970-01-01
    • 2012-06-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-10-10
    • 1970-01-01
    相关资源
    最近更新 更多