2015-03-26 14 views
9

Utilizzando una versione leggermente modificata di Howard Hinnants's C++11 stack allocator che è documented here e here, con std::basic_string e compilazione con gcc che sta usando libstdc++, il seguente esempio (see it live):Il C++ 11 richiede che gli allocatori siano costruttibili di default, libstdC++ e libC++ non sono d'accordo?

const unsigned int N = 200; 

arena<N> a; 
short_alloc<char, N> ac(a) ; 

std::basic_string<char,std::char_traits<char>,short_alloc<char, N>> empty(ac); 

pronunciato la seguente errore (tra gli altri):

error: no matching function for call to 'short_alloc<char, 200ul>::short_alloc()' 
    if (__n == 0 && __a == _Alloc()) 
        ^

Tuttavia, funziona senza errori durante la compilazione con clang e utilizzando libc++ (see it live).

L'implementazione stdlibc++ di std::basic_string prevede che l'allocatore abbia un costruttore predefinito.

Il C++ 11 richiede che gli allocatori siano costruttibili di default? Quale implementazione è corretta?

+2

domande Self-risposta ottieni automaticamente un downvote. Ho una buona idea di chi sia, ma nessuna prova. In ogni caso, hanno bisogno di risucchiarlo perché la politica sulle domande auto-risposte (è _ esplicitamente incoraggiata_, e ci sono anche le opzioni della GUI !!) è stata collegata a loro molte volte ma non sembrano accettarle. –

risposta

7

No, C++ 11 non richiede un allocatore avere costruttore di default, se guardiamo al C++ 11 sezione standard progetto 17.6.3.5[allocator.requirements] Contiene Tabella 28requisiti Allocator che non contenere un requisito per un costruttore di default e in seguito nella sezione viene fornita un'interfaccia conforme minima:

[Esempio: il seguente è un modello di classe allocatore sostenere l'interfaccia minimale che soddisfi i requisiti della tabella 28:

template <class Tp> 
struct SimpleAllocator { 
    typedef Tp value_type; 
    SimpleAllocator(ctor args); 

    template <class T> SimpleAllocator(const SimpleAllocator<T>& other); 

    Tp *allocate(std::size_t n); 
    void deallocate(Tp *p, std::size_t n); 
}; 

-end esempio]

che non contiene un costruttore predefinito.

C'è un rapporto libstdc++ bug: basic_string assumes that allocators are default-constructible che dice:

Il vuoto-stringa di ottimizzazione del basic_string presuppone che allocatori sono costruibili di default. Mentre questo era il caso in C++ 98, lo non è più vero in C++ 11, poiché ora gli allocatori possono avere lo stato .

Considerare il programma di esempio allegato. Compilare con

g++ -std=c++11 -c t.cpp 

produce un messaggio di errore, anche se deve essere compilato correttamente. Il problema è il "_S_construct" chiama "_Alloc()", che non esiste .

Si noti che lo standard C++ 11 non richiede costruttori predefiniti. (Sezione 17.6.3.5, Tabella 28). In particolare, l'esempio SimpleAllocator della Sezione 17.6.3.5 attiverà anche lo stesso bug.

e la risposta è stata:

Questo non è certo l'unico requisito C++ 11 allocatore manca std :: string, tutti i nuovi requisiti mancano, ed è improbabile che essere attuato fino a quando passiamo a un'implementazione di stringhe non COW.

Questa è fissato come di gcc 5.0:

fissati per GCC 5 (quando si utilizza la nuova stringa ABI)

Possiamo confermare questa utilizzando gcc 5 on wandbox