2015-05-07 13 views
5

Angenommen, ich möchte throw mit einer Zeichenfolge, die Informationen über ein Objekt enthält, aber die Objekt-Implementierung hat nur eine Überladung für den Stream-Operator (<<) statt eine Umwandlung in Zeichenfolge. Ich möchte so etwas wie dies zu tun:Kann ich die Überladung des Stream-Operators ohne ein Stream-Objekt aufrufen?

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

wo x eine Instanz eines Typs ist, der hat (<<) überlastet. Das obige funktioniert jedoch nicht, da + nicht zu einem Typ überkomprimiert wird, der mit const char* kompatibel ist. Wenn x einen String (oder gießbaren in einen String) waren es funktionieren würde, aber stattdessen muss ich dies tun:

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

Wie kann ich etwas so prägnant wie im ersten Beispiel erhalten, ohne Überlastungen oder benutzerdefinierte Funktionen hinzufügen. Bietet die Standardbibliothek einige Funktionen, die hier helfen?

+0

Überlastung 'operator + (std :: string &, X &)' – 101010

+0

Können Sie nicht Überladen Sie das +, um dem Objekt eine Zeichenfolge hinzuzufügen? – MiltoxBeyond

+0

@MiltoxBeyond Ich könnte, aber ich stelle die Frage zu sehen, ob es möglich ist, es zu tun, ohne überhaupt neue Funktionen/Überlastungen zu schreiben. – arman

Antwort

4

Sie können auf eine Funktion delegieren:

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

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

die auch was boost::lexical_cast tut:

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

Oder Sie können einen temporären Strom verwenden, die seit operator<< eine Besetzung zu tun beinhaltet, die konventionell gibt nur eine basic_ostream<char>&:

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

Oder Sie diese Logik in eine separate Art wickeln können, die, wenn gestreamt, um das Ergebnis zu einem string umwandelt, um ihrer selbst willen Belustigung:

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. Korrigiert. – Barry

+0

@ T.C. Warum '&&'? – Barry

+0

Meine Bearbeitungszusammenfassung zitieren: "Um libC++ zu plazieren, die in diesem Fall einen' ostringstream && 'zurückgibt, der nicht in 'ostringstream &' umgewandelt werden kann. " –

Verwandte Themen