Невозможно использовать пользовательский распределитель с allocate_shared / make_shared

В моей программе на C ++ 11 я использую shared_ptr<T> для некоторых объектов, которые активно создаются и удаляются. Случилось так, что стандартный распределитель с operator new является узким местом, поэтому я хочу создать свой собственный, который будет выделять кучу памяти сразу, а затем отдавать make_shared по требованию. К сожалению, это первый раз, когда я пишу распределитель, и я понятия не имею, почему GCC не может скомпилировать следующий код:

#include <memory>

class MyAlloc {
public:
  typedef char* pointer;
  typedef const char* const_pointer;
  typedef char value_type;

  char* allocate(size_t len) {
    return new char[len];
  }

  void deallocate(char *ptr) {
    delete[] ptr;
  }
} my_alloc;

int main() {
  std::allocator_traits<MyAlloc>();
  // MyAlloc is a correct allocator, since allocator_traits can be instantiated
  // If I comment the following line of code, compilation is successful
  std::allocate_shared<int>(my_alloc, 0);
  return 0;
}

Здесь у меня очень простой распределитель-заглушка и один вызов allocate_shared. GCC выдает ошибку:

In file included from c:\soft\mingw\lib\gcc\mingw32\4.8.1\include\c++\ext\alloc_traits.h:36:0,
                 from c:\soft\mingw\lib\gcc\mingw32\4.8.1\include\c++\bits\stl_construct.h:61,
                 from c:\soft\mingw\lib\gcc\mingw32\4.8.1\include\c++\memory:64,
                 from a.cpp:1:
c:\soft\mingw\lib\gcc\mingw32\4.8.1\include\c++\bits\alloc_traits.h: In substitution of 'template<class _Alloc> template<class _Tp> using rebind_traits = std::allocator_traits<typename std::__alloctr_rebind<_Alloc, _Tp>::__type> [with _Tp = std::_Sp_counted_ptr_inplace<int, MyAlloc, (__gnu_cxx::_Lock_policy)2u>; _Alloc = MyAlloc]':
c:\soft\mingw\lib\gcc\mingw32\4.8.1\include\c++\bits\shared_ptr_base.h:517:33:   required from 'std::__shared_count<_Lp>::__shared_count(std::_Sp_make_shared_tag, _Tp*, const _Alloc&, _Args&& ...) [with _Tp = int; _Alloc = MyAlloc; _Args = {int}; __gnu_cxx::_Lock_policy _Lp = (__gnu_cxx::_Lock_policy)2u]'
c:\soft\mingw\lib\gcc\mingw32\4.8.1\include\c++\bits\shared_ptr_base.h:986:35:   required from 'std::__shared_ptr<_Tp, _Lp>::__shared_ptr(std::_Sp_make_shared_tag, const _Alloc&, _Args&& ...) [with _Alloc = MyAlloc; _Args = {int}; _Tp = int; __gnu_cxx::_Lock_policy _Lp = (__gnu_cxx::_Lock_policy)2u]'
c:\soft\mingw\lib\gcc\mingw32\4.8.1\include\c++\bits\shared_ptr.h:316:64:   required from 'std::shared_ptr<_Tp>::shared_ptr(std::_Sp_make_shared_tag, const _Alloc&, _Args&& ...) [with _Alloc = MyAlloc; _Args = {int}; _Tp = int]'
c:\soft\mingw\lib\gcc\mingw32\4.8.1\include\c++\bits\shared_ptr.h:598:39:   required from 'std::shared_ptr<_Tp1> std::allocate_shared(const _Alloc&, _Args&& ...) [with _Tp = int; _Alloc = MyAlloc; _Args = {int}]'
a.cpp:19:40:   required from here
c:\soft\mingw\lib\gcc\mingw32\4.8.1\include\c++\bits\alloc_traits.h:204:66: error: invalid use of incomplete type 'struct std::__alloctr_rebind<MyAlloc, std::_Sp_counted_ptr_inplace<int, MyAlloc, (__gnu_cxx::_Lock_policy)2u>, false>'
         using rebind_traits = allocator_traits<rebind_alloc<_Tp>>;
                                                                  ^
c:\soft\mingw\lib\gcc\mingw32\4.8.1\include\c++\bits\alloc_traits.h:65:12: error: declaration of 'struct std::__alloctr_rebind<MyAlloc, std::_Sp_counted_ptr_inplace<int, MyAlloc, (__gnu_cxx::_Lock_policy)2u>, false>'
     struct __alloctr_rebind;
            ^

Почему это происходит? Как правильно написать распределители, чтобы они работали с allocate_shared? Я знаю, что есть некоторые другие операторы и черты типов, которые должны поддерживаться распределителем, но я не вижу ни одного намека на то, что GCC хочет от меня.

Кроме того, можно ли использовать char в качестве value_type для этого конкретного распределителя (в сочетании с shared_ptr) или что-то вроде void или shared_ptr<T>::some_weird_stuff предпочтительнее?

8
задан yeputons 18 March 2014 в 06:55
поделиться