2015-10-21 6 views
7

Sto cercando di associare nuovamente il mio tipo allocatore personalizzato, MyAllocator<foo>, per l'uso in una classe basic_string, ad esempio:Lo std :: allocator_traits definisce rebind_alloc se rebind non è presente nell'allocatore personalizzato?

std::basic_string<char, std::char_traits<char>, MyAllocator<char>> ...

L'allocatore viene passato al contesto come MyAllocator<void>, quindi ho bisogno di associare nuovamente l'allocatore .

Dalla pagina cppreference per std::allocator_traits, http://en.cppreference.com/w/cpp/memory/allocator_traits:

gli alias modelli:

rebind_alloc<T>: Alloc::rebind<T>::other se presenti, altrimenti Alloc<T, Args> se questo Alloc è Alloc<U, Args>

miei attrezzi allocatore personalizzato allocator_traits, ma non definisce la struttura di rebind (che non è un è necessario essere in grado di implementare allocator_traits). La mia comprensione della documentazione è che deve comprendere allocator_traitsrebind_alloc. Tuttavia, se cerco di chiamare rebind_alloc sul mio tipo allocatore personalizzato:

template<typename T> 
using RebindAlloc = 
    typename std::allocator_traits<MyAllocator<void>>::template rebind_alloc<T>; 

ottengo vari errori di compilazione quando si tenta di passare RebindAlloc<char> al tipo basic_string:

In file included from /usr/bin/../lib/gcc/x86_64-linux-gnu/4.8/../../../../include/c++/4.8/string:52: 
/usr/bin/../lib/gcc/x86_64-linux-gnu/4.8/../../../../include/c++/4.8/bits/basic_string.h:114:41: error: 
    'rebind' following the 'template' keyword does not refer to a template 
    typedef typename _Alloc::template rebind<_CharT>::other _CharT_alloc_type; 

Chiaramente la documentazione mi ha ingannato. Dovrei semplicemente rinunciare allo rebind_alloc e implementare il rebind nell'allocatore personalizzato, oppure esiste un modo corretto di farlo usando allocator_traits?

Sto utilizzando gcc 4.8 con C++ 11. 14 non è un'opzione al momento.

Ecco un frammento di codice di quello che sto cercando di fare: https://gist.github.com/jacquelinekay/0cee73d1d2d78d8edd31

+0

puoi pubblicare un minimo (quasi) esempio compilabile che posso collegarlo il mio compilatore per controllare? –

+1

L'ho modificato con uno snippet di codice che dovrebbe essere valido, tranne per l'errore di compilazione menzionato nel post originale che non riesco a capire. – Jackie

+0

@Jackie compila bene a partire da gcc 5.1 –

risposta

4

Sto utilizzando gcc 4.8 con C++ 11.

allora avete bisogno di definire rebind nel vostro allocatore, del GCC basic_string non supporta i requisiti allocatore C++ 11 fino alla versione 5.1 (e solo per la nuova stringa ABI, vale a dire std::__cxx::basic_string).

Così il vostro allocatore deve soddisfare i requisiti C++ 03 allocator, definendo tutti i membri, perché allocator_traits non viene utilizzato da stringa a 4,8

1

n3376 dice in [allocator.traits.types]/10:

template <class T> using rebind_alloc = see below; 

modello Alias:Alloc::rebind<T>::other se tale tipo esiste; altrimenti, Alloc<T, Args> se Alloc è un'istanza modello di classe del modulo Alloc<U, Args>, dove Args è zero o più argomenti tipo; in caso contrario, l'istanziazione di rebind_alloc non è corretta.

che è d'accordo con cppreference. Esso (tratti allocatori) sembra essere stato aggiunto in C++ 11, quindi non appare in n1905. Ulteriore archeologia potrebbe rilevare dove è arrivato, ma quello non è tutto ciò che è rilevante.

Sembra che il compilatore non sia un compilatore C++ 11 conforme a questo proposito.

Con le correzioni minori, both gcc 5.2.0 and clang 3.7.0 in C++11 mode compila il codice senza errori.

Sembra l'unica risposta ragionevole, se non è possibile modificare il compilatore, è quello di implementare un semplice rebind.

Problemi correlati