Интерфейсы C ++ 11 Allocator по умолчанию, которые я должен предоставить

Создавая свой собственный распределитель в C ++ 11, я реализую следующие интерфейсы. Это работает с вектором, но при попытке использовать это с картой я получаю ошибки по отсутствующим элементам. Я думал, что это все, что мне нужно реализовать для C ++ 11, поскольку он будет использовать allocator_traits в реализациях stl. Что мне здесь не хватает? Нужно ли мне определять больше методов / структур данных для распределителя для std :: map? При попытке компиляции я вижу следующие ошибки (см. Ниже). Строка 3 main.cpp - это просто

#include <map>

template <class T> struct MyAllocator {
    typedef T value_type;
    MyAllocator() noexcept;  // only required if used
    MyAllocator(const MyAllocator&) noexcept;  // copies must be equal
    MyAllocator(MyAllocator&&) noexcept;  // not needed if copy ctor is good enough
    template <class U> MyAllocator(const MyAllocator<U>& u) noexcept; 
        // requires: *this == MyAllocator(u)
    value_type* allocate(std::size_t);
    void deallocate(value_type*, std::size_t) noexcept;
};

template <class T, class U> bool
operator==(const MyAllocator<T>&, const MyAllocator<U>&) noexcept;

Ошибки:

Первые ошибки решаются с помощью некоторых определений типов в MyAllocator:


person bjackfly    schedule 23.10.2014    source источник
comment
некоторые из ваших строк излишне длинные   -  person bjackfly    schedule 23.10.2014
comment
Не могли бы вы опубликовать MCVE? Так людям будет проще вам помочь. Ideone - полезный инструмент, позволяющий с меньшим количеством беспорядка продемонстрировать ошибки компиляции.   -  person sp2danny    schedule 23.10.2014
comment
Вероятно, что gcc-4.8.1 просто еще не реализует полную спецификацию C ++ 11 в этой области.   -  person Fabio A. Correa    schedule 23.10.2014
comment
спасибо @HowardHinnant проголосовали за   -  person Howard Hinnant    schedule 23.10.2014
comment
Как странно. Согласно Учебному пособию и справочнику по стандартной библиотеке C ++ Николая М. Йосуттиса (2-е издание), стр. 1026, вам не нужно предоставлять construct () или destroy (), потому что их реализации по умолчанию обычно работают нормально. Перед этим он сказал, что вы должны предоставить / a: (1) определение value_type (2) конструктор (3) конструктор шаблона (4) функции-члены allocate () и deallocate () (5), если необходимо, конструкторы и деструктор (6) операторы == и! =. Для остальных обычно предоставляются соответствующие значения по умолчанию.   -  person bjackfly    schedule 24.10.2014


Ответы (2)


Пожалуйста, опубликуйте свой новый результат компиляции.

typedef T& reference;
typedef const T& const_reference;
typedef T* pointer;
typedef const T* const_pointer;

В основном, как предполагал мой комментарий, мне нужно было поместить определения типов для следующего, а также построить и уничтожить

person Fabio A. Correa    schedule 23.10.2014

обратите внимание, что это работает после добавления construct, destroy и некоторых определений типов для указателя и т. д. Просто во всей литературе я не думал, что мне это нужно.

        template <class U> 
        struct rebind {typedef MyAlloc<U, N> other;};  

        typedef size_t size_type;                                                                                                                                                                                                      
        typedef ptrdiff_t difference_type;
        typedef T* pointer;
        typedef const T* const_pointer;
        typedef T& reference;                                                                                                                                                                                                          
        typedef const T& const_reference;                                                                                                                                                                                              
        typedef T value_type;          

       /// Call constructor with many arguments                                                                                                                                                                                       
        template<typename U, typename... Args>                                                                                                                                                                                         
        void construct(U* p, Args&&... args)                                                                                                                                                                                           
        {                                                                                                                                                                                                                              
            // Placement new                                                                                                                                                                                                           
            ::new((void *)p) U(std::forward<Args>(args)...);                                                                                                                                                                           
        }                                                                                                                                                                                                                              
        /// Call destructor                                                                                                                                                                                                            
        template<typename U>                                                                                                                                                                                                           
        void destroy(U* p)                                                                                                                                                                                                             
        {                                                                                                                                                                                                                              
            p->~U();                                                                                                                                                                                                                   
        }                           
person bjackfly    schedule 23.10.2014
comment
В файле, включенном из /opt/gcc-4.8.1/usr/local/include/c++/4.8.1/map:61:0,
из main.cpp: 3:
/opt/gcc-4.8 .1 / usr / local / include / c ++ / 4.8.1 / bits / stl_map.h: при создании экземпляра 'class std :: map, MyAlloc>':
main.cpp: 146: 14: требуется отсюда < br> /opt/gcc-4.8.1/usr/local/include/c++/4.8.1/bits/stl_map.h:143:58: ошибка: нет типа с именем 'указатель' в 'std :: map, MyAlloc> :: _ Pair_alloc_type {он же класс MyAlloc, 200 typedef typename _Pair_alloc_type :: указатель указателя; ^
/opt/gcc-4.8.1/usr/local/include/c++/4.8.1/bits/stl_map.h:144:58: ошибка: нет типа с именем 'const_pointer' в 'std :: map, MyAlloc> :: _ Pair_alloc_type {aka class MyAlloc /opt/gcc-4.8.1/usr/local/include/c++/4.8.1/bits/stl_map.h:145:58: ошибка: нет типа с именем 'ссылка' в ' std :: map, MyAlloc> :: _ Pair_alloc_type {он же class MyAlloc, 2 typedef typename _Pair_alloc_type :: reference reference; ^
/opt/gcc-4.8.1/usr/local/include/c++/4.8.1/bits/stl_map.h:146:58: ошибка: нет типа с именем 'const_reference' в 'std :: map, MyAlloc> :: _ Pair_alloc_type {aka class MyAlloc В файле, включенном из /opt/gcc-4.8.1/usr/local/include/c++/4.8.1/map:60:0,
из main.cpp: 3:
/opt/gcc-4.8.1/usr/local/include/c++/4.8.1/bits/stl_tree.h: при создании экземпляра 'void std :: _ Rb_tree ‹_Key, _Val, _KeyOfValue, _Compare, _Alloc> :: _ M_destroy_node (std :: _ Rb_tree ‹_Key, _Val, _KeyOfValue, _Compare, _Alloc> :: _ Link_t /opt/gcc-4.8.1/usr/local/include/c++/4.8.1/bits/stl_tree.h:1124 : 23:
требуется от 'void std :: _ Rb_tree ‹_Key, _Val, _KeyOfValue, _Compare, _Alloc> :: _ M_erase (std :: _ Rb_tree‹ _Key, _Val, _KeyOfValue, _Compare, _Alloc> :: _ Link_type / opt / gcc-4.8.1 / usr / local / include / c ++ / 4.8.1 / bits / stl_tree.h: 671: 28:
требуется от 'std :: _ Rb_tree ‹_Key, _Val, _KeyOfValue, _Compare, _Alloc>: : ~ _Rb_tree () [с _Key = int; _Val = std :: pair; _KeyOfValue = std ::
/opt/gcc-4.8.1/usr/local/in clude / c ++ / 4.8.1 / bits / stl_map.h: 96: 11:
требуется отсюда
/opt/gcc-4.8.1/usr/local/include/c++/4.8.1/bits/ stl_tree.h: 421: 2: error: 'std :: _ Rb_tree, std :: _ Select1st>, std :: less, MyAlloc, 200ul>>:
_M_get_Node_allocator (). destroy (__ p); ^
make: *** [main.o] Ошибка 1 - person Olumide; 11.12.2014