Sono un po 'curioso di alcune delle nuove funzionalità di C++ 0x. In particolare range-based for loops e initializer lists. Entrambe le funzionalità richiedono una classe definita dall'utente per funzionare correttamente.C++ 0x, ganci del compilatore e caratteristiche dei linguaggi hard codificati
Mi sono imbattuto in this post e mentre la risposta in alto era utile. Non so se è completamente corretto (Probabilmente sono solo completamente frainteso, vedi 3 ° commento sulla prima risposta). Secondo il current specifications per le liste di inizializzazione, l'intestazione definisce un tipo:
template<class E> class initializer_list {
public:
initializer_list();
size_t size() const; // number of elements
const E* begin() const; // first element
const E* end() const; // one past the last element
};
Si può vedere questo nelle specifiche, semplicemente Ctrl + F 'classe initializer_list'.
Affinché = {1,2,3}
per essere implicitamente fuso nella classe initializer_list
, il compilatore deve avere una certa conoscenza della relazione tra {}
e initializer_list
. Non c'è costruttore che riceve qualcosa, quindi l'inizializzatore_list per quanto posso dire è un wrapper che viene associato a qualsiasi cosa il compilatore stia effettivamente generando.
È lo stesso con la for(:)
ciclo, che richiede anche un tipo definito dall'utente lavorare (se secondo le specifiche, aggiornati non richiede alcun codice per array e liste di inizializzazione. Ma elenchi di inizializzazione richiedono <initializer_list>
, quindi è un requisito del codice definito dall'utente per proxy).
Sto fraintendendo completamente come funziona qui? Non mi sbaglio nel pensare che queste nuove funzionalità si basino in maniera estremamente pesante sul codice utente. Sembra come se le funzionalità fossero semicipite, e invece di costruire l'intera funzione nel compilatore, è fatta a metà dal compilatore e metà inclusa in include. Qual è la ragione di questo?
Modifica: Ho digitato "fare molto affidamento sul codice del compilatore" e non "fare molto affidamento sul codice utente". Che penso abbia completamente gettato via la mia domanda. La mia confusione non riguarda le nuove funzionalità incorporate nel compilatore, sono cose che sono incorporate nel compilatore che si basano sul codice utente.
Posso capire il requisito per il costrutto for (:), senza il compilatore che richiede un'iterazione differente del contenitore sarebbe impossibile. Ma for (:) non richiede che un tipo funzioni, solo se intendi estenderlo. Quale per me si sente simile al nuovo meccanismo di sovraccarico di posizionamento. Tuttavia, non vedo ancora il motivo dell'elenco initializer_type. = {1,2,3,4,5} a un letterale di array, passato a un operatore void {} (int arr [], 5); sembra più pulito e non richiede sistemi di inclusione. Se l'utente vuole inserirla in un contenitore, può farlo in quella funzione. – Dave
Proprio come hai menzionato va_args, le funzioni e le macro sono basate su una funzione del compilatore. Non otterrai un errore del compilatore per non includere va_args, potresti scrivere il tuo. Allo stesso modo C++ 0x []() {} lambda non richiede std :: function, potresti ancora scriverne uno tuo. {} d'altra parte richiede l'esistenza di un nome di classe specifico, che andrà in crash se non esiste. E non dovrebbe essere forzato, immagino di essere solo un "nerd furioso", ma molto di quello che vedo nello standard C++ 0x sembra essere sempre più alieno di minuto in minuto. – Dave
È un po 'più complicato di così. Il compilatore e gli implementatori di STL non devono essere uguali. Microsoft utilizza l'implementazione di Dinkunware STL, ma è possibile utilizzare STLPort o qualsiasi altro. Le classi STL non sono definite al 100% e inchiodate e un implementatore STL può decidere di aggiungere nuovi parametri del modello purché abbiano un valore predefinito e possano quindi essere utilizzati nel codice utente che dipende e utilizza solo quelli dello standard. Ciò significa che il compilatore non può realmente abbinare facilmente i contenitori STL da solo. –