E 'in effetti un po' fastidioso, non avendo parentesi operatore quadrato per std :: initializer_list, come la necessità di un accesso diretto casuale per un indice specifico è uno scenario ragionevole.
Tuttavia, questa capacità può essere aggiunto con un certo codice semplice:
// the class _init_list_with_square_brackets provides [] for initializer_list
template<class T>
struct _init_list_with_square_brackets {
const std::initializer_list<T>& list;
_init_list_with_square_brackets(const std::initializer_list<T>& _list): list(_list) {}
T operator[](unsigned int index) {
return *(list.begin() + index);
}
};
// a function, with the short name _ (underscore) for creating
// the _init_list_with_square_brackets out of a "regular" std::initializer_list
template<class T>
_init_list_with_square_brackets<T> _(const std::initializer_list<T>& list) {
return _init_list_with_square_brackets<T>(list);
}
ora abbiamo una nuova funzione globale chiamato _ (trattino basso), che probabilmente non è un buon nome per il metodo di un C globale ++, a meno che non voglio creare una utility lib di tipo "undescore" per C++, che avrà il proprio spazio dei nomi, sovraccaricando la funzione _ per tutti gli altri usi utili.
La nuova _ funzione può essere utilizzata ora come questo:
void f(std::initializer_list<int> list) {
cout << _(list)[2]; // subscript-like syntax for std::initializer_list!
}
int main() {
f({1,2,3}); // prints: 3
cout << _({1,2,3})[2]; // works also, prints: 3
return 0;
}
E 'da notare che la soluzione fornita di cui sopra non è un buon affare in termini di prestazioni se si esegue nel corso di molti elementi di std: : initializer_list, come oggetto temporaneo del tipo suggerito sopra _init_list_with_square_brackets
viene creato ripetutamente. Che, naturalmente, fa sorgere la meraviglia perché questo non è stato fornito dallo standard stesso.
fonte
2015-10-09 14:56:43
Indovino perché il suo caso d'uso principale deve essere una lista che viene elaborata in sequenza. – PlasmaHH
Un caso d'uso comune è per un costruttore che assegna un blocco di memoria e costruisce gli elementi nel blocco usando 'allocator.construct (p, v)'.Mentre la lista è ancora processata in modo sequenziale, il ciclo for esterno ha già un contatore che si presta alla sintassi 'operator []'. –
@ void-pointer Non sareste normalmente * copiati * in queste circostanze? In questo modo non hai bisogno di un ciclo e in genere eviterei comunque un ciclo esplicito. La domanda è ancora valida, però. –