2012-02-08 14 views
22

Conosco std::queue::pop() restituisce void. Per due motivi: sicurezzaCan queue: pop restituisce un valore ora?

  1. eccezione: qualcosa potrebbe gettare dopo aver rimosso l'elemento
  2. per poter return the value by reference

fine.

Ora, se capisco correttamente la nuova semantica del C++ 11, il secondo non è più un argomento valido.

Quindi ... l'unica cosa che impedisce a std::queue di avere una funzione pop -like che restituisce il valore si trova nella possibilità che il costruttore di mosse genera?

Ho difficoltà a pensare a situazioni in cui un costruttore di mosse potrebbe buttare. Chi conosce un esempio?

immagino lo stesso vale per std::stack::pop(), std::vector::pop_front(), std::vector::pop_back(), std::deque::pop_front(), std::deque::pop_back(), std::list::pop_front(), std::list::pop_back() e cosa no.

+0

Queste sono davvero due domande. Un esempio per un costruttore di mosse di lancio e un pop di ritorno. – pmr

+0

Ho bisogno di un esempio di un costruttore di lancio per capire perché non possiamo avere il 'pop' di ritorno. –

+3

E i tipi che non hanno un costruttore di mosse? – jalf

risposta

5

Utilizzando tecniche SFINAE intelligente sarebbe infatti possibile avere un pop_and_move non gettando atomica() per soli tipi di dati che implementano non-lancio mossa o no-gettare copia.

C'è anche un costrutto noexcept() disponibile per vedere se qualcosa potrebbe generare.

Uno dei nuovi concetti in C++ 11 in particolare che estende SFINAE è che se il corpo non compila la funzione non esiste. Quindi si potrebbe implementare basato su noexcept().

Direi che per la compatibilità con le versioni precedenti la funzione avrebbe bisogno di un nuovo nome, che pertanto le consente di coesistere con la funzionalità esistente di chiamarle separatamente, non di rompere contenitori di tipi che non hanno la semantica per consentirli.

+0

Potresti approfondire l'estensione di SFINAE in C++ 11 (un riferimento standard sarebbe bello)? Non ne ho mai sentito parlare e vorrei saperne di più. – Grizzly

+1

E 'stato menzionato da Alexandrescu nel suo discorso sui modelli variadici nella conferenza Going Native. Come parte del principio di "fallimento della sostituzione non è un errore", se il corpo non compilerebbe questo è considerato un errore di sostituzione troppo (quindi ignorare questa specializzazione). Con noexcept() è probabilmente possibile creare già una funzione che utilizzerebbe lo spostamento se disponibile e non-throwing, quindi userebbe la copia come seconda scelta se è disponibile e non si lancia, e non riesce a compilare altrimenti. – CashCow

+1

Suoni promettenti! Questa risposta non è la risposta più diretta alle mie domande, ma è in realtà ciò che stavo cercando senza saperlo. –

6

Non ci sono molti casi in cui std::move() può inserire nella libreria standard ma ci sono casi. Ad esempio, se il contenitore utilizza un allocatore di stato, i suoi figli usano anche questo allocatore, ma non verrà spostato su un risultato: questo preferirebbe ottenere una versione costruita di default di un allocatore (se rimuovo correttamente). Dato che gli allocatori sono stateful, ciò significa che l'oggetto non può essere spostato e quindi la costruzione dello spostamento non riesce con un'eccezione. Perché questo tipo ha quindi un costruttore di mosse? Bene, perché potrebbe essere istanziato con un allocatore non statico, nel qual caso il movimento non verrà lanciato. Inoltre, una volta che passiamo alle classi definite dall'utente, non abbiamo idea di quali condizioni possano spostarle.

+0

Finisci per dare a tante domande una svolta interessante. Un giorno in cui avrò il tempo di esaminare il tuo profilo e leggere tutte le tue risposte a tutto. – odinthenerd

1

Un altro problema è che non tutte le classi traggono vantaggio dallo spostamento, vale a dire che potrebbero avere solo un copione.

struct DontLikeMoves{ 
    // some data, whatever... 
    DontLikeMoves(DontLikeMoves const& other){ 
    // might throw, who knows! 
    // and this will even get called for rvalues 
    } 
}; 
Problemi correlati