Devo usare un enorme dizionario con chiavi integer (o enum) e valori di stringa. Ma questo è totalmente costante. Non c'è modo di cambiare in runtime. Esiste un modo (utilizzando modelli, ecc.) Per recuperare i dati del dizionario in fase di compilazione invece di utilizzare la struttura del dizionario esistente?Quale struttura dati utilizzare per un dizionario enorme ma costante in C++
risposta
Clang e LLVM hanno risolto il problema generando tabelle contenenti i loro oggetti, utilizzando una combinazione di generazione del codice e trucchi del preprocessore.
È possibile saltare entrambi i passaggi, in base alla propria configurazione. Per esempio:
// records.inc
EXPAND_RECORD(Foo, "Foo", 4);
EXPAND_RECORD(Bar, "Bar", 18);
EXPAND_RECORD(Bar2, "Bar", 19);
Ora, è possibile generare il vostro enum:
// records.h
enum Record {
#define EXPAND_RECORD(Name, String, Value) Name,
#include "records.inc"
#undef EXPAND_RECORD
};
char const* getRecordName(Record r);
int getRecordValue(Record r);
// records.cpp
char const* getRecordName(Record r) {
switch(r) {
#define EXPAND_RECORD(Name, String, Value) case Name: return String;
#include "records.inc"
#undef EXPAND_RECORD
}
abort(); // unreachable, or you can return a "null" value
}
int getRecordValue(Record r) {
switch(r) {
#define EXPAND_RECORD(Name, String, Value) case Name: return Value;
#include "records.inc"
#undef EXPAND_RECORD
}
abort(); // unreachable, or you can return a "null" value
}
In Clang e LLVM, una fase di generazione di codice viene utilizzato per generare il .inc dai file di definizione più piacevole.
Funziona molto bene ... ma sii consapevole che qualsiasi modifica dell'enumerazione implica la piena ricompilazione. Si potrebbe desiderare di andare a un approccio "codeset", in cui l'enum viene usato internamente ma mai fuoriuscito, e i valori stabili (quelli dell'enum) vengono forniti al client (unsigned
), in modo che i vecchi client possano collegarsi al nuovo librerie senza ricompilazione: saranno limitate ad usare il vecchio set di codici, che non è un problema se è stabile.
Sicuramente si può semplicemente utilizzare sed per trasformare il dizionario in una stringa costante indicizzato dal parametro del modello, con un file di intestazione come:
template <int Index> struct Dictionary { static const char *entry; };
e un file sorgente con molte linee della forma:
template <> const char *Dictionary<5>::entry = "Entry for five";
D'altra parte, vuoi davvero farlo dal punto di vista della manutenzione? Implica la ricompilazione per ogni voce del dizionario modificata e dimensioni esecuzioni gonfiate.
* Bloated *: beh, la voce deve essere da qualche parte, almeno averla in ROM significa che non è duplicata tra varie istanze del programma (se DLL). * Ricompilazione *: potrebbe essere un problema, a meno che non si disponga di un'interfaccia corretta. –
Informazioni sulla generazione automatica del codice? Prendi il file di configurazione o il database o qualunque sia l'origine e generi codice di intestazione C++ da quello. Potrebbe essere simile a questa:
#define MYCONST_1 "#00ff00"
#define MYCONST_10 "My other configuration string"
Si può fare la conversione con un semplice script bash o con Ruby/Python (o C++ se siete masochisti), dipende dalla complessità del file di configurazione.
Quindi scrivere alcune regole di creazione per creare automaticamente i file di intestazione quando il file di configurazione cambia.
Ho un grande fan che mi fa scendere di testa tutto il tempo senza mai commentare .. –
Oups mi dispiace per quello, stavo cucinando in quel momento e temo di aver dimenticato il commento: x In primo luogo, questo non affronta il enum <-> mappatura stringa uno iota. Secondo * per favore * non usare macro per letterali/costanti, ci sono alternative migliori (costante esterna, costante statica, ecc ...). –
- 1. Struttura dati C# come un dizionario ma senza valore
- 2. Dizionario struttura dati in R
- 3. Quale struttura dati utilizzare nel mio esempio
- 4. Quale struttura dati utilizzo qui?
- 5. Quale struttura dati usare?
- 6. Miglior struttura dati in C++ per trovare una stringa in un dizionario
- 7. La migliore struttura dati per implementare un dizionario?
- 8. Quale struttura dati per una matrice di bit di bit?
- 9. Creare enorme dizionario
- 10. Struttura enorme del grafico
- 11. Struttura dati per implementare un dizionario con più indici?
- 12. Quale struttura dati C# consente di cercare le stringhe in modo più efficiente per le sottostringhe?
- 13. Come rendere i puntatori di funzione in una costante di struttura da utilizzare per inizializzare un array costante?
- 14. Struttura database per struttura dati ad albero
- 15. Quale struttura dati dovrei usare per la classe BigInt
- 16. Javascript: quale struttura la funzione da utilizzare
- 17. Lettura da un enorme MemoryStream in C#
- 18. Quale struttura di ORM rubino utilizzare in un'app rubino autonoma?
- 19. Quale struttura dati sarebbe la migliore per questo?
- 20. Impossibile rendere il campo della struttura come costante in C
- 21. Quale struttura dati è ragionevole per i dati delle serie temporali in Java?
- 22. Struttura dati per un mondo casuale
- 23. C#: dichiarazione di una variabile costante per il tipo di dati da utilizzare
- 24. struttura dati per Albero familiare
- 25. Quale tipo di struttura dati dovrei utilizzare per contenere le righe della tabella?
- 26. Come posso utilizzare Nokogiri per scrivere un file XML ENORME?
- 27. come utilizzare il dizionario bidirezionale in C#
- 28. Esercitazione per struttura dei dati dell'albero in C
- 29. Genera un'immagine enorme in C#
- 30. Struttura dati per processo decisionale Markov
Da dove provengono i dati? I modelli non possono leggere da un file, per esempio. Quindi la risposta è, molto probabilmente, che non puoi farlo al momento della compilazione. –
@Oli: puoi sempre # includere i file. –
Non possono, ma forse è possibile trasformare il file di configurazione in un file C++ prima della compilazione. la generazione automatica del codice potrebbe risolvere il problema. –