Reputation: 483
I want to write an assert function that works like this:
//the following expression outputs "assertion failed" to std::err and then terminates the program
assert(false) << "assertion " << "failed";
What I have so far is this:
#include <stdlib.h>
#include <iostream>
#include <string>
class AssertHelper
{
public:
AssertHelper(bool state):assert_state(state){};
AssertHelper operator<<(const std::string &mesg){
if(!assert_state){
std::cerr << mesg << std::endl;
std::cerr.flush();
exit(-1);
}
return *this;
};
private:
bool assert_state;
};
AssertHelper assert(bool cond){
return AssertHelper(cond);
}
int main(){
assert(false) << "assertion" << " failed";
}
But my way of implementing it only displays the first part of the message "assertion". How can I print the second (and potentially third, fourth...) part of the message before terminating?
Upvotes: 1
Views: 117
Reputation: 515
Don't check the assertion every time you stream something into your object. Use the fact that your object will be destroyed at the end of the statement by checking and flushing in AssertHelper
's destructor.
Your operator<<
should be as simple as this:
AssertHelper& operator<<(const T &v) {
_message << v;
return *this;
}
Note that you return a reference to the same object, making the next call to <<
stream into the same object! Make _message
a member variable that you can stream into like a std::stringstream
. And in the destructor do this:
~AssertHelper(){
if(!assert_state){
std::cerr << _message.str() << std::endl;
exit(-1);
}
}
Upvotes: 3
Reputation: 26292
Minimal correction:
const AssertHelper& operator<<(const std::string& mesg) const
{
if (!assert_state)
std::cerr << mesg;
return *this;
};
~AssertHelper()
{
if (!assert_state)
{
std::cerr << std::endl;
exit(-1);
}
}
Remarks: operator<<
should return a reference, not a value; bool assert_state;
can be marked as const
; calling flush()
after << std::endl
is superfluous.
Upvotes: 1