Geltend machen mit der dynamischen Botschaft?
In meinem Programm möchte ich behauptet, dass eine Fehlermeldung anzeigen. Abgesehen von den bekannten Problemumgehungen für C und C++ gibt es die "echte" Lösung als BOOST bietet BOOST_ASSERT_MSG( expr, msg )
(siehe auch assert() mit der Meldung)
Aber eine statische Nachricht ist nicht genug für mich, ich möchte auch zeigen, manchmal fehlgeschlagenen Variablen, z.B. in einem Fall wie
BOOST_ASSERT_MSG( length >= 0, "No positive length found! It is " << length )
Wie Sie sehen können ich möchte zum formatieren der Nachricht enthält "string" als stringstream
oder ostream
wie, dass würde mir erlauben, mich leicht zeigen, benutzerdefinierte Typen (vorausgesetzt, ich habe definiert die relevanten formatieren-Funktion).
Hier das problem, dass BOOST_ASSERT_MSG
ist standardmäßig erfordern eine char const *
so dass es nicht kompatibel ist.
Gibt es eine Möglichkeit neu zu definieren /überlast assertion_failed_msg()
in der Weise, dass über einen stream als Nachricht funktionieren??? Wie?
(Mein naiver Ansatz gescheitert, da der compiler zuerst wollten operator<<("foo",bar)
auf die Nachricht selbst...)
Du musst angemeldet sein, um einen Kommentar abzugeben.
Definieren Sie Ihre eigenen makro -
while(0)
?while(0)
weglassen;
.Ist es relativ einfach, dies zu erreichen.
error: ‘struct std::basic_ostream<char>’ has no member named ‘str’
static_cast<std::stringstream&>()
den Rückgabewertoperator<<()
nutzen zu könnenstd::stringstream::str()
. Sonst bist du versucht, zu rufenstd::ostream::str()
, die nicht existiert.Ich die
BOOST_ASSERT_MSG
mit meinen eigenen wrapper um ihn herum, so dass die Angabe der assert-Nachricht mit mehrerenoperator<<
scheint weniger Komplex.Beispiel, stellen Sie benutzerdefinierte Nachricht, wie Sie die Ausgabe auf
cout
:Was es tut, ist, wenn
ASSERT_ENABLED
definiert ist,ermöglichen die Geltendmachung Nachrichten.if(!(cond))
Teil ist die Optimierung, vermeidet die kostspielige string-Operationen angegeben, die durch makro-parametermsg
, wenncond
isttrue
#if defined ASSERT_ENABLED
? Ich denke, wenn assert deaktiviert ist, werden die Anweisungen entfernt werden, jedenfalls, wenn Sie eine compiler-Optimierung. Bin ich richtig?#if defined ASSERT_ENABLED
ist für die Optimierung. In der Regel builds gemeint sind mit assertions deaktiviert. Dieser entfernt den code aus der binären. Kleiner binären, weniger code, bessere Nutzung der cache-Anweisung. Während geltend machen, spart viel Zeit beim Debuggen. Manchmal, ein einfaches assert-check sparen könnte 3-Tage-debugging-Zeit.Hier ist eine Lösung, die sich nicht auf Makros. Stattdessen verwendet es ein winziges bisschen templating und lambda-syntax.
Dem argument
fn
kann jede aufrufbar.Zum Beispiel können Sie nennen es so:
Der Vorteil ist, dass die Ausgabe ist, dass Sie nicht ruft abort (explizit und die Ausgabe ist vollständig anpassbar. Das dieser Vorteil natürlich, sind die sieben zusätzlichen Zeichen des lambda-Funktion boilerplate:
[&](){}
)