Uso dei typedef pubblici nei tipi di classi template

2

Recentemente ho preso l'abitudine di typedef in vari tipi all'interno delle classi template, come avviene nella libreria standard. Ad esempio, una classe contenitore potrebbe sembrare qualcosa sulla falsariga di:

template<typename T>
class custom_container {
public:
    typedef T value_type;
    typedef value_type* pointer;
    typedef value_type& reference;
    typedef std::size_t size_type;

    reference operator[](size_type);

    // etc...
};

Tuttavia, dopo un po 'di utilizzo di questo, ho iniziato a chiedermi se fosse davvero una buona idea, nonostante la leggibilità e l'espressione di intenti presumibilmente aumentate.

Sembra controintuitivo che si possa alias, diciamo, T in un altro tipo, dal momento che nessuno usa la classe aspettandosi che value_type sia T , e solo sempre T in ogni caso ( è un custom_container<T> dopo tutto)? Allo stesso modo, gli utenti di tale classe non sempre si aspettano che pointer sia T* e reference come T& ?

Usiamo typedef s per consentire la facilità di modificare un tipo di aliasing in un altro se necessario, tuttavia nella maggior parte dei casi che ho riscontrato, detto typedef s è ridondante e quasi confuso, poiché non avrebbe mai senso avere l'alias sinonimo di qualsiasi altro tipo. custom_container probabilmente non soddisferebbe le sue aspettative se value_type è stato cambiato in qualsiasi altra cosa di T - l'utente si aspetta che sia una sorta di contenitore di T s.

Quindi, è ancora utile e / o un buon design fare un uso pesante di typedef s nelle classi template come fatto nella libreria standard?

    
posta MC ΔT 04.08.2017 - 18:39
fonte

2 risposte

1

Quelle di typedef non sono solo per te da usare direttamente nel codice normale.

Sì, a volte potrebbero essere più descrittivi rispetto a specificare direttamente il tipo o consentire di verificare che effettivamente utilizzi il tipo giusto per il lavoro.

Inoltre, in C ++ l'11% diauto e% didecltype hanno preso il posto del lavoro per la maggior parte, ed è molto più conveniente e più difficile da sbagliare.

Ci sono ancora casi limite lasciati, per esempio quando hai tipi di proxy come in std::vector<bool> .

E naturalmente, trovare manualmente il tipo giusto potrebbe essere un po 'ostacolato quando si scrivono i modelli.

Nello standard c'è un motivo in più per usare quei typedef nell'interfaccia: nomi-argomento, template o funzione, sono solo per esposizione.

    
risposta data 04.08.2017 - 19:31
fonte
1

Questi typedef sono utili per due motivi:

  • per abbreviare i nomi di tipi molto complicati come i tipi di iteratore.

  • per scrivere codice generico robusto che faccia uso del tuo modello e non sia a conoscenza di T . Pre C ++ 11 non puoi scrivere codice generico senza usare questi typedef, o almeno non senza complicati template helper.

Entrambi questi motivi sono meno necessari poiché C ++ 11: decltype() può essere usato per trovare molti tipi come il tipo di valore, e auto può essere usato per evitare di compitare nomi di tipi complicati.

Ma entrambi hanno dei limiti.

  • decltype() a volte può produrre tipi imprevisti, specialmente attorno a constness, riferimenti o quando sono coinvolte conversioni implicite. Per esempio. dato un std::vector<bool> xs , value_type è bool ma decltype(xs[0]) sarebbe un oggetto di riferimento wrapper, a meno che xs sia const, nel qual caso è nuovamente bool . La contabilità corretta (forse tramite std::decay ?) È molto difficile.

  • Poiché auto si risolverà felicemente con qualsiasi tipo, non è adatto quando si desidera documentare e applicare un tipo specifico. In alcuni punti come i parametri di funzione non è possibile utilizzare auto (sebbene questo sia già consentito da alcuni compilatori come dichiarazione di un modello di funzione implicito).

risposta data 04.08.2017 - 19:34
fonte

Leggi altre domande sui tag