operator << überladen
-
Hallo,
Ich habe den operator<< überladen:class Exception { const Exception& operator<< (std::string val) { Parameter.push_back(val); return(*this); } };Jetzt habe ich folgende Zeile:
throw Exception(ExceptionType::IndexOutOfRange) << index << valWirft diese Zeile eine Exception(ExceptionType::IndexOutOfRange), in die index und val eingefügt wurden? Oder verstehe ich etwas daran falsch?
Danke schon im Voraus.
mfg
Mr X
-
Ja, sollte so gehen. Der Ausdruck
Exception(ExceptionType::IndexOutOfRange)erzeugt ein temporäres Objekt, auf den
operator<<angewandt wird. Der Operator gibt wiederum ein temporäres Objekt zurück. Schlussendlich wirfst du das Resultat des gesamten Ausdrucks, also die Verkettung aller Einfügungen.P.S.: Eine Alternative wäre
operator(). Kann ja sein, dass dir das syntaktisch besser gefällt:throw Exception(ExceptionType::IndexOutOfRange)(index)(val);
-
Ok, Danke.
Dann habe ich es ja geschafft, eine einfache Syntax für meine Klasse zu erzeugen.
-
Ich habe noch was reineditiert, das auch die Syntax betrifft.

Ach ja, und ich würde Const-Referenz-Parameter nehmen. Was mir auch noch aufgefallen ist: Der Operator sollte eine Referenz auf Non-
constzurückgeben, sonst kann das Resultat nicht mehr verändert werden.
-
Der operator<< gefällt mir irgendwie besser (STL-Stream-Klassen ähnlich).
Ich hab das jetzt so verändert:
class Exception { Exception& operator<< (const std::string& val) { Parameter.push_back(val); return(*this); } };Ich musste das const beim Rückgabetyp entfernen, weil die Referenz nicht const sein darf, da ich auf sie ja den nicht-konstanten operator<< ausführe.
-
Nur so als genereller Hinweis:
Bei Exception-Klassen solltest du aber vorsichtig sein bzgl. Memory-Allocation, sonst kriegst du evtl. darin dann eine OutOfMemory-Exception beim 'vector::push_back'.
-
eventuell="quasi nie, und wenn ja, war eh bereits alles verloren".
Ein Nachteil an der Klasse ist meiner Meinung nach, dass sie nicht von std::exception abgeleitet ist. Aber vielleicht ist das auch nur ein Codeausschnitt und im original ist sie das

-
throw Exception(ExceptionType::IndexOutOfRange) << index << val;sieht aber leicht eklig aus

wenn überhaupt dann würde ich so was hier schreiben wollen:Exception e(ExceptionType::IndexOutOfRange); e << index << val; throw e;den operator<< würde ich außerhalb der klasse definieren und die würde in etwa so aussehen:
struct Exception : std::runtime_error { /*CTOR und ggf. what() fehlt noch*/ template<typename T> void to_add(const T& to_add) { std::stringstream ss; ss << to_add; to_add(ss.str()); } void to_add(const std::string& to_add) { data.push_back(to_add); } private: std::vector<std::string> data; }; template<typename T> Exception& (Exception& these, const T& to_add) { Exception.Add(to_add); return these; } void test() { int index; double val; std::cin >> index; val = 3.14159265*index; if(index > 5) { Exception e(ExceptionType::IndexOutOfRange); e << index << val; throw e; } } int main() { for(;;) { try { foo(); } catch(Exception& e) { std::cout << "cought: " << e.what() << std::endl; } } }Wenn du mit der Exception auch bad_alloc signalisieren können möchtest, müsstest du im
to_add(std::string)testen, ob dein enum bad_alloc sagt und wenn ja, dann einfach nichts machen. (aber eigtl wirst du ja bei bad_alloc kaum noch daten mitgeben wollen?!)
Oder du schreibst dir nen Allokator, der Platz aufm Stack nimmt - iwo hier gibts nen STL-Allocator-Thread, dort hab ich heut früh oder so nen Bsp. gepostet, wie man so was machen könnte - du müsstest ihn nur etwas anpassen oder im ctor auch gleich nen reserve machen...
dann hast du nur noch mit dem stringstream nen Problem - dem kannst du aber imho auch keinen allocator mitgeben...den enum-ansatz würd ich btw auch nicht nehmen sondern mit templates arbeiten - dann könnte man den bad_alloc-Fall entsprechend spezialisieren...
bb
-
unskilled, du hast etwas wichtiges (operator <<) vergessen:
template<typename T> Exception& operator<<(Exception& these, const T& to_add) { Exception.Add(to_add); return these; }Oder meintest du, weil es ja im Titel des Beitrags steht, brauchst du es nicht noch mal hinschreiben?

P.S: what is "cought:"???
-
Th69 schrieb:
P.S: what is "cought:"???
Ein Schreibfehler

-> catch -> caught
Etwas (ab)fangen, in dem Fall eine Exception.
-
1.:
template<typename T> Exception& (Exception& these, const T& to_add) { Exception.Add(to_add); return these; }hier fehlt einfach noch operator<< - sry^^
so macht das stück hier natürlich nicht all zu viel sinn
2.:
wollt noch was zum knobeln übriglassen ;o)bb