Передайте конструктор класса через аргумент шаблона в С++

Я знаю, что функция может проходить через аргумент template, могу ли я передать конструктор класса следующим образом.

Обновление: Вся причина, по которой я хочу это сделать, заключается в том, что я могу выбрать конструктор в пуле памяти и без какого-либо изменения кода в классе, который я хочу выделить (в данном случае class A)

class A
{
public:
  A(){n=0;}
  explicit A(int i){n=i;}

private:
  int n;
};

class MemoryPool
{
public:
   void* normalMalloc(size_t size);
   template<class T,class Constructor>
   T* classMalloc();
};

template<class T,class Constructor>
T* MemoryPool::classMalloc()
{
   T* p = (T*)normalMalloc(sizeof(T));
   new (p) Constructor; // choose constructor
   return p;
}

MemoryPool pool;
pool.classMalloc<A,A()>(); //get default class
pool.classMalloc<A,A(1)>();

person xucheng    schedule 07.01.2012    source источник
comment
A() в аргументе шаблона обозначает тип функции, не принимающей аргументов и возвращающей A.   -  person Xeo    schedule 07.01.2012
comment
Не могли бы вы предоставить больше контекста? Учитывая только эту небольшую информацию, я бы спросил себя: почему бы не использовать new A() напрямую вместо new_func<A, A()>? Иными словами, что вам дает new_func? Он абстрагируется от построения?   -  person Andre    schedule 07.01.2012
comment
@Andre Причина в том, что я хочу использовать его в пуле памяти, чтобы я мог выделить класс с выбором конструкции.   -  person xucheng    schedule 08.01.2012
comment
Вы были бы удовлетворены, если бы вы могли ввести pool.classMalloc<A>(); и pool.classMalloc<A>(1); ? На самом деле это было бы довольно легко сделать.   -  person Aaron McDaid    schedule 08.01.2012
comment
Но для пула памяти аргумент конструктора класса malloc неизвестен.   -  person xucheng    schedule 08.01.2012
comment
@ michael911009 Вы читали FAQ по C++ о размещении нового [parashift .com/c++-faq-lite/dtors.html#faq-11.10] и пулы памяти [parashift.com/c++-faq-lite/dtors.html#faq-11.14]? Похоже, это может быть полезно для вас.   -  person Andre    schedule 08.01.2012


Ответы (3)


Вы не можете обойти конструкторы, но можете обойти фабричные функторы:

class A
{
    int n;

    A(int i) : n(i) {};

public:

    static A* makeA(int i)
    {
        return new A(i);
    }
};

template<typename T, typename Factory>
T* new_func(Factory factory)
{
    return factory();
}

#include <functional>

int main()
{
    new_func<A>(std::bind(&A::makeA, 0));
    new_func<A>(std::bind(&A::makeA, 1));
}
person fredoverflow    schedule 07.01.2012
comment
Вся причина, по которой я хочу это сделать, заключается в том, что я могу выбрать конструктор в пуле памяти и без изменения кода в классе, который я хочу выделить - person xucheng; 08.01.2012

Все ваше предположение неверно. Вам не нужна эта функция.

template<class T>
T* new_func()
{
   return new T;
}

То, что стоит после new, — это тип, а не ссылка на конструктор.

person Johannes Schaub - litb    schedule 07.01.2012
comment
Как насчет разницы между new A() и new A(1) - person xucheng; 07.01.2012
comment
Это не проходит конструктор. Это передаст полный список аргументов. Это даже не работает для обычных (членов) аргументов шаблона указателя функции. Конечно, вы должны передать это как обычные аргументы функции, а не как аргументы шаблона. Прочтите или спросите об идеальной переадресации. - person Johannes Schaub - litb; 07.01.2012
comment
Добавьте параметр в new_func(): T* new_func(int i = 0) и передайте его конструктору. - person hmjd; 07.01.2012
comment
Вся причина, по которой я хочу это сделать, заключается в том, что я могу выбрать конструктор в пуле памяти и без изменения кода в классе, который я хочу выделить - person xucheng; 08.01.2012
comment
@ michael911009, вам разрешено использовать C++11? Он имеет некоторые функции, которые могут быть очень полезными. Короче говоря, вы хотите иметь возможность ввести что-то вроде pool.classMalloc<ANY_TYPE>(any_arguments_that_can_construct_that_type), не так ли? - person Aaron McDaid; 08.01.2012
comment
C++0x удовлетворяет, но я не знаю, как - person xucheng; 08.01.2012

Так лучше я думаю

template<class T, int n>
struct Factory
{
  static T* new_func()
  {
     return new T(n);
  }
};

template<class T>
struct Factory<T,0>
{
  static T* new_func()
  {
     return new T;
  }
};

T* t = Factory<T>::new_func(); //call default constructor
T* t2 = Factory<T,2>::new_func(); //call constructor T(2)
person nttstar    schedule 08.01.2012
comment
Вся причина, по которой я хочу это сделать, заключается в том, что я могу выбрать конструктор в пуле памяти и без изменения кода в классе, который я хочу выделить - person xucheng; 08.01.2012
comment
Вы можете использовать стиль Factory в своем классе пула памяти. - person nttstar; 08.01.2012
comment
Это раздражает, что каждый раз, когда я использую его. Мне нужно написать новую структуру Factory, так как аргумент конструктора класса malloc неизвестен - person xucheng; 08.01.2012
comment
Проверьте мой ответ на этот вопрос: stackoverflow.com/questions/ 8711542/ - person nttstar; 08.01.2012