Quali sono i vantaggi dell'utilizzo di boost.anuna libreria? Potresti per favore darmi alcuni esempi di vita reale? Perché non è stato possibile ottenere la stessa funzionalità avendo un qualche tipo generico nella radice della gerarchia dell'oggetto e creando contenitori con quel tipo di base?Qual è l'uso tipico di potenziare qualsiasi libreria?
risposta
Ritengo che Boost.Variant debba sempre essere preferito in quanto non invadente e richiede ancora una programmazione molto strutturata.
Ma credo che l'idea principale di boost.any sia quella di fornire l'equivalente dei tipi di oggetti java e C#. È un modo per dire "sì, possiamo"! :-)
boost :: any memorizzerà felicemente interi e float, tipi che chiaramente non hanno classi base. Un esempio di vita reale in cui è possibile utilizzarlo è una macchina virtuale per un linguaggio interpretato di alto livello. I tuoi oggetti "funzione" avranno bisogno di una serie di argomenti. Questo può essere facilmente implementato con un std::list<boost::any>
dietro le quinte.
Perché non è stato possibile ottenere la stessa funzionalità con un tipo generico nella radice della gerarchia dell'oggetto e la creazione di contenitori con quel tipo di base?
Che chiama una gerarchia di oggetti - un costrutto che si sta iniettando artificialmente nel design per risolvere un problema periferico. Inoltre, un tale costrutto è facile da sbagliare e un'implementazione sbagliata può causare il caos. Boost.Any
è una comunità esaminata alternativa sicura e ben collaudata.
Potrebbe per favore darmi alcuni esempi di vita reale?
TinyJSON utilizza boost.Any
.
Quali sono i vantaggi dell'utilizzo di boost.una libreria?
Mi riferisco alla documentazione introductory.
Per rappresentare JSON in C++ 'boost :: variant
Non ho scritto quella libreria :-) Sono sicuro che hai valide ragioni. – dirkgently
Utilizziamo boost.any come tipo di operatore per un contenitore variadic con tag di sicurezza del tipo. Ecco cosa significa:
Abbiamo un oggetto "zattera", che viaggia attraverso una serie di filtri. Quando un filtro vuole aggiungere dati alla zattera, si può fare qualcosa di simile:
raft.addTaggedData<ETag1>(3.0);
raft.addTaggedData<ETag2>("a string")`;
std::string str = raft.getTaggedData<ETag2>();
int a = raft.getTaggedData<ETag1>(); // <-- Compile error
Dove ETag1
e ETag2
sono membri di un enum, e usiamo un modello di tratti per mappare i tag per i tipi.
La classe di zattera utilizza un list
di pair<ETagType, boost::any>
come archivio di supporto. Boost.any ci ha risparmiato il dolore di gestire i buffer grezzi per vari tipi.
Usando un po 'di boost.MPL, potresti usare boost.Variant invece di Boost.Any. –
Anche usando boost.any era persino un po 'allungato; il mio team è piuttosto prudente quando si tratta di funzionalità C++. Inoltre, non ho ancora imparato MPL. :) –
@ Benoît Boost.Variant richiederebbe alla zattera di conoscere tutti i tag possibili (o almeno i loro tipi di valore). Questo potrebbe non essere possibile se per esempio la zattera fluttua attraverso moduli indipendenti che potrebbero immagazzinare un tipo di dati privati in questo modo. O anche se è possibile potrebbe non essere desiderato a causa delle maggiori dipendenze di origine implicite in questo modo. Anche se Boost.Any aumenta i costi di runtime quindi è un trade-off. –
Lo abbiamo utilizzato in una mappa delle proprietà, (std::map<std::string, boost::any>
), per archiviare molte cose dinamicamente in uno spazio dati semplice e piatto.
Per lo più abbiamo memorizzato oggetti o stringhe smart-ptr-to-scriptable, ma alcune voci in cui altri tipi (float, vec3f, matrici e altri oggetti non standard).
Funziona molto bene per aggiungere ulteriori funzionalità dinamiche a C++, o ovunque si desideri cancellare il tipo per aggiungere qualsiasi tipo di dati a un oggetto.
Quando ho appreso per la prima volta di Boost, ho trovato this article da Herb Sutter e Jim Hyslop nel Dr. Dobbs. L'ho trovato utile.
Boost.Variant non può sostituire Boost.Any nel caso in cui il tipo da tenere è noto in fase di esecuzione. Ad esempio, vedere il collegamento indicato nel commento di SCFrench: http://www.ddj.com/cpp/184403808 –
-1. Boost.any può memorizzare tutti i tipi, anche quelli primitivi, non solo gli equivalenti di oggetti "C#/java". – Macke
@Macke Non dire C#/java in questo caso. C# (CLR) può memorizzare un valore primitivo in un oggetto. Le lingue possono sembrare simili, ma differiscono. – erikkallen