Ho creato un tipo di flusso personalizzato, chiamandolo error_stream
, che deriva da std::ostringstream
. Ho anche creato un manipolatore personalizzato per lo stream chiamato throw_cpp_class
(throw_cpp
è un'istanza di throw_cpp_class
). Il mio obiettivo era quello di avere questa sintassi:È ragionevolmente efficiente inserirli in un riferimento di rvalue a un flusso?
error_stream s;
s << "some error " << message() << throw_cpp; // throw_cpp throws an exception containing contents of the stream.
ho scoperto che attraverso la definizione di un operatore di inserimento che prende un riferimento rvalue al flusso come primo operando, ora posso fare questo:
error_stream() << "some error " << message() << throw_cpp;
Il L'operatore di inserimento è simile al seguente:
error_stream& operator<<(error_stream&& s, const throw_cpp_class&)
{
throw s.str();
return s;
}
Cosa sta succedendo qui? Perché è possibile restituire un valore di tipo error_stream&&
in cui è richiesto un error_stream&
? (Questo richiama il costruttore di mosse?). È orribilmente inefficiente? (Non che mi importi davvero, dato che l'eccezione dovrebbe essere rara).
Questo è in realtà un po 'pulito ... Penso che potrei preferire 'throw_cpp' però, per lanciare quell'errore con il contenuto dello stream. –
Rilascerei il tipo restituito e l'istruzione 'return os'. È un errore semantico scrivere 's <<" qualche errore "<< messaggio() << throw_cpp <<" more ";'. Restituendo 'void', diventa anche un errore di sintassi e il compilatore lo prenderà. – MSalters
@MSalters - buon punto. Ho fatto il cambiamento. – 0xbe5077ed