Как создать универсальную функцию вставки для пользовательского контейнера с функтором

На данный момент, я не беспокоюсь о том, что это правильное решение для моей проблемы (на самом деле, это не так), но я попал в эту проблему, и я не мог ее решить, поэтому она преследует меня, и я не могу отпустить.

У меня есть универсальный контейнер для типов 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, потому что я даже не знаю, сколько параметров понадобится следующей функции init_xxx, которая понадобится пользователю для его типа pod. Я начал играть с идеей передачи второго шаблона параметра в класс 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:(

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 ... */
Другие вопросы по тегам