Come leggere un valore con l'operatore > > ma nessun costruttore predefinito per il valore?
-
08-07-2019 - |
Domanda
template <class T>
T Read () {
T t;
cin >> t;
if (cin.fail()) {
// ...
}
return t;
}
Questo codice generico legge il valore di tipo T con una gestione degli errori aggiuntiva. Si basa sull'avere operatore > > che può analizzare T, e in questo modo è estensibile a nuovi tipi.
Quello che non ho realizzato è che si basa sul fatto che T ha un costruttore predefinito. Ora ho colpito questo problema.
Quali sono le mie opzioni?
Qual è il modo giusto per farlo?
Soluzione
Lo streaming da un flusso di input presuppone sempre un oggetto completamente costruito in cui scrivere. Non puoi evitare di dover costruire un oggetto, tutto ciò che puoi fare è consentire diversi modi per farlo.
Un modo per farlo potrebbe essere tratto. I tratti standard farebbero quello che stai facendo:
template< typename T >
struct istream_traits
{
inline static T read(std::istream& is)
{
T obj;
is >> obj;
}
}
template< typename T >
inline T read(std::istream& is)
{
is >> std::ws;
T obj = istream_traits<T>::read(is);
is >> std::ws;
if(!is.eof()) throw "dammit!";
return obj;
}
Se hai un tipo X
che non può essere costruito di default, ma può essere costruito da un istream, la seguente specializzazione farebbe:
template<>
struct istream_traits<X>
{
inline static X read(std::istream& is)
{
return X(is);
}
}