(Re)denominato std::pair membri
Invece di scrivere town->first
vorrei scrivere town->name
. Inline denominato funzioni di accesso (Ridenominazione di primo e secondo di un iteratore mappa e Nome std::pair membri) sono le soluzioni migliori che ho trovato finora. Il mio problema con il nome di funzioni di accesso è la perdita di sicurezza del tipo:
pair<int,double>
può fare riferimento a struct { int index; double value; }
o struct { int population; double avg_temp; }
. Chiunque può proporre un approccio semplice, forse qualcosa di simile per caratteristiche?
Spesso vuole il ritorno di una coppia o di una tupla da una funzione ed è molto faticoso, per introdurre un nuovo tipo come struct city { string name; int zipcode; }
e la sua ctor ogni volta. Io sono entusiasti di conoscere boost e C++0x, ma ho bisogno di un puro C++03 soluzione senza boost.
Aggiornamento
Re andrewdski domanda: sì, un (ipotetico) sintassi come pair<int=index, double=value>
che avrebbe creato un tipo distinto da pair<int=population, double=avg_temp>
sarebbe soddisfare le vostre esigenze. Non ho neanche idea di dover implementare una coppia personalizzato/tupla modello di classe una VOLTA e solo di passaggio un ‘nome tratti modello argomento è approprietly quando ho bisogno di un nuovo tipo. Non ho idea di come che ‘nome tratti sarebbe simile. Forse è impossibile.
- Come non è, questo, un problema reale? Perché il downvote?
- Vorrei sapere anche questo.
- Il downvote è il pensiero che ogni oggetto con due membri dovrebbero ereditare da std::pair e rinominare i membri. Non abbiamo bisogno di std::tripla e std::quad per i più grandi oggetti?!
- Persson: si dovrebbe leggere la domanda prima di downvoting: dove mi ha fatto ricordare ereditarietà?
- Persson C’è std::tupla / boost::tupla per oggetti più grandi.
- Forse il problema è che la gente non riesce a capire cosa stai chiedendo. Tu dici di voler distinguere tra
struct { int index; double value; }
estruct { int population; double avg_temp; }
, ma si vuole fare questo semplicemente rinominando coppia membri? Come in tutto il mondo come vorrei che lavoro? Sembra certo, come si desidera una struct. (E per la cronaca, io non downvote.) - Sì, vedi che il mio problema in modo corretto. Vorrei riutilizzare std::pair, e rinominare i suoi membri, in QUALCHE modo. Se sapevo la risposta come, non vorrei fare questa domanda. 🙂
- Ma questi sono per i tipi con unnamed membri.
- Questo potrebbe essere un lavoro per le macro per creare le strutture di cui avete bisogno, se si vuole risparmiare un po ‘ di digitare ogni volta
- Come, altrimenti, sarebbero i tipi di ottenere i membri di una coppia?
- Persson sono d’accordo – che eredita da std::pair o tutto ciò che è stupido. Volevo solo dire perché non abbiamo bisogno di un std::tripla e std::quad.
- Così un (ipotetico) sintassi come
pair<int=index, double=value>
che avrebbe creato un tipo distinto dapair<int=population, double=avg_temp>
sarebbe soddisfare le vostre esigenze? - Downvoting senza commento è giustificata dal fatto che qualcuno non capisce qualcosa o è un malinteso? È necessario disporre di downvoted ogni domanda, allora. (Da notare che non ha mai detto nulla sull’ereditarietà comunque, io non sono abbastanza sicuro di quello che è.)
- Ho downvoted durante i 30 minuti prima ha curato la domanda. Era solo per non comprensibile. Come si fa a modificare una classe senza ereditare da essa?!
- Persson: non ho mai parlato di ereditarietà, è possibile controllare facilmente la storia. Da tratti, è possibile collegare le informazioni per classi, senza modificarle. Non so come funzionerebbe in questo caso, per cui la questione.
- Sì. Non ho neanche idea di dover implementare una coppia personalizzato/tupla modello di classe una VOLTA e solo di passaggio a nome dei tratti a approprietly in ogni caso ho bisogno di un nuovo tipo. Tuttavia, il riutilizzo di std::pair è preferito.
- Non è possibile modificare i nomi dei membri con tratti, si può? E non è possibile modificare un classe’ comportamento senza la eredita e l’override delle funzioni virtuali. Ho appena trovato la prima domanda davvero stupida a causa di questo, ma ovviamente le persone non sono d’accordo.
- Persson: per la domanda originale, da dove scrivo di modifica di comportamento?
- Hmmm sembra che ho perso la parte in cui hai detto che non vuoi impiegare boost 🙂 in questo caso @dalle risposta dovrebbe essere ok (a parte le ‘basta usare una struct con il coro, che è a destra, ma noioso)
Non vedo come si possa fare di meglio
Non c’è niente di non-essenziale non c’. Hai bisogno di tipi, di due membri, di tutta la tua domanda è basata intorno a dare il nome alle due membri, e si desidera essere un tipo unico.
Fare conoscere la sintassi di inizializzazione aggregata, giusto? Non hai bisogno di un costruttore o di un distruttore, il compilatore fornito quelli che vanno più che bene.
Esempio:
http://ideone.com/IPCuwTipo di sicurezza richiede l’introduzione di nuovi tipi, altrimenti
pair<string, int>
è ambiguo tra (nome, il codice postale) e (popolazione, temp).In C++03, la restituzione di una nuova tupla richiede:
o la scrittura di una comodità costruttore:
per ottenere
Con il C++0x, tuttavia, vi sarà permesso di scrivere
e nessun utente-definito costruttore è necessario.
string
l’inizializzazione aggregata sintassi non funziona.std::string
all’interno. Gcc accetta con-ansi
. Si prega di non prendere il mio primo commento in conto.return { "new york", 10001 };
alla fine di una funzione. Quindi è ancora necessario scrivere un costruttore e scriverereturn city("new york", 10001);
. Ho bisogno di un puro C++03 soluzione.city retval = { "new york", 10001 }; return retval;
? Dopo “Denominato Valore di Ottimizzazione di Ritorno”, che praticamente tutti i moderni compilatori, sarà la stessa.typedef pair<string /*name*/,int /*zipcode*/> city;
etypedef pair<string /*street*/,int /*number*/> building;
(2) In C++0x si sarà in grado di scriverereturn { "new york", 10001 };
(3) Nel frattempo si sia scrivere un costruttore o una o l’aggiunta di un’ulteriore linea dicity retval = { "new york", 10001 }; return retval;
ogni volta che una città è tornato. Grazie!Anche se non perfetto, è possibile utilizzare i tag di dati:
Ma come Ben Voigt dice:
struct city { string name; int zipcode; };
sarebbe praticamente sempre essere migliore.EDIT: Modelli sono probabilmente eccessivo, si potrebbe utilizzare la connessione funzioni in uno spazio dei nomi, invece. Questo ancora non risolve il tipo di problemi di sicurezza, come qualsiasi
std::pair<T1, T2>
dello stesso tipo di quella di qualsiasi altrostd::pair<T1, T2>
:typedef std::pair<std::string /*street*/, int /*number*/> building;
. Che era il mio problema con il nome di funzioni di accesso.std::pair<T1, T2>
dello stesso tipo di quella di qualsiasi altrostd::pair<T1, T2>
. Se si desidera che il tipo di sicurezza è necessario utilizzare diversi tipi.struct city { string name; int zipcode; };
è davvero la soluzione più semplice, e con il C++0x sarò in grado di utilizzare l’inizializzazione aggregata.Dal
std::pair
è comunemente utilizzato per la memorizzazione di vocistd::map
contenitori, si potrebbe desiderare di guardare tagged elementi Boost Bimap.Sinossi:
Nota che bimaps in modo trasparente possono emulare
std::map
o altri associativo tipi di contenitore senza costo delle prestazioni; solo Che sono più flessibili. In questo particolare esempio, la definizione sarebbe più probabile essere cambiato in qualcosa di simile:Vi invito a passeggiare per la documentazione per Aumentare Bimap per avere il quadro completo
Credo elaborando
è il più vicino si arriva a quello che stai cercando, althrough
struct City { string name; int zipcode; }
sembra perfettamente bene.Sarete felici di sapere che gli intervalli proposta include anche un qualcosa che si chiama
tagged_pair
, in modo che la vostra:può anche essere scritto come:
Naturalmente, questo può essere utilizzato anche nel tipo di ritorno direttamente come normale:
È possibile utilizzare il puntatore-a-membro operatori. Ci sono un paio di alternative. Qui è il più semplice.
Si può mettere le funzioni di accesso per uno pseudo-tipo, in un apposito
namespace
che li separa da altre cose. Quindi, sarebbe simile amy_map_value.*zip::name
. Ma, a meno che non si ha realmente bisogno di utilizzare unpair
, probabilmente è più facile, basta definire una nuovastruct
.Mi si avvicinò con un
Utility_pair
macro che può essere utilizzata come questo:Quindi, ogni volta che è necessario per accedere ai campi di
ValidityDateRange
, si può fare come questo:Questo è l’implementazione:
Penso che si dovrebbe davvero introdurre nuovi tipi qui. Io sono totalmente su stl in termini di avere una coppia di classe, ma questo è l’esatto motivo per cui java persone sostengono che non vuole avere un paio di classe e si dovrebbe sempre introdurre nuovi tipi per la vostra piar-come tipi.
La buona cosa circa il stl soluzione è che si può usare il generico classe di coppia, ma è possibile introdurre nuovi tipi di classi di ogni volta che si vuole veramente i membri a essere chiamato in modo diverso da prima/seconda. In cima a che l’introduzione di nuove classi ti dà la libertà di facilmente aggiungere un terzo membro, se dovesse essere necessario.
forse si può ereditare il tuo paio di classe in coppia e set di due riferimenti chiamato il nome e il codice postale nel costruttore ( basta essere sicuri di implementare tutti i costruttori si usa )
std::pair
non sono un distruttore virtuale, quindi questo potrebbe portare ad accidentali perdite di memoria.std::pair
codersource.net/c/c-miscellaneous/c-virtual-destructors.aspx