2015-05-07 10 views
5

Supponiamo di voler inserire throw con una stringa contenente informazioni su alcuni oggetti, ma l'implementazione dell'oggetto ha solo un sovraccarico per l'operatore di flusso (<<) anziché un cast per stringa. Voglio fare qualcosa di simile:Posso richiamare il sovraccarico dell'operatore di flusso senza un oggetto flusso?

throw std::runtime_error("Error, encountered invalid value " + x); 

dove x è un'istanza di un tipo che ha (<<) sovraccarico. Quanto sopra non funziona, tuttavia, poiché lo + non è sovraccarico su un tipo compatibile con const char*. Se x erano una stringa (o calcinabile a una stringa) che avrebbe funzionato, ma invece devo fare questo:

std::stringstream s; 
s << "Error, encountered invalid value " << x; 
throw std::runtime_error(s.str()); 

Come posso ottenere qualcosa di più conciso come il primo esempio senza l'aggiunta di eventuali sovraccarichi o funzioni personalizzate. La libreria standard fornisce alcune funzionalità che aiuteranno qui?

+0

sovraccarico 'operatore + (std :: string &, X &)' – 101010

+0

può non sovraccaricare il + per aggiungere una stringa all'oggetto? – MiltoxBeyond

+0

@MiltoxBeyond Potrei, ma sto facendo la domanda per vedere se è possibile farlo senza scrivere nuove funzioni/sovraccarichi. – arman

risposta

4

È possibile delegare a una funzione:

template <typename T> 
std::string stream(const T& x) { 
    std::ostringstream ss; 
    ss << x; 
    return ss.str(); 
} 

throw std::runtime_error("Error..." + stream(x)); 

che è anche quello che boost::lexical_cast fa:

throw std::runtime_error("Error..." + boost::lexical_cast<std::string>(x)); 

oppure è possibile utilizzare un flusso temporanea, che prevede di dover fare un cast dal operator<< convenzionalmente restituisce solo un basic_ostream<char>&:

throw std::runtime_error(
    static_cast<std::ostringstream&&>(std::ostringstream{} << "Error..." << x) 
    .str()); 

Oppure si può avvolgere la logica in un tipo separato che, quando in streaming, converte il risultato a un string, per l'amor di divertimento:

struct ToStrT { 
    friend std::string operator<<(std::ostream& os, ToStrT) { 
     return static_cast<std::ostringstream&&>(os).str(); 
    } 
}; 

constexpr ToStrT ToStr{}; 

throw std::runtime_error(std::ostringstream{} << "Error..." << x << ToStr); 
+0

@ T.C. Corretto. – Barry

+0

@ T.C. Perché '&&'? – Barry

+0

Citazione del mio sommario di modifica: "Per placare libC++, che restituisce un' ostringstream && 'in questo caso, che non può essere lanciato su' ostringstream & '" –

Problemi correlati