megamonium
megamonium

Reputation: 483

How to write a custom assert function that accepts assert messages like this: assert(false) << "assertion" << " failed";

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

Answers (2)

Sebastian Schmitz
Sebastian Schmitz

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

Evg
Evg

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

Related Questions