如何编写一个接受断言消息的自定义断言函数,如下所示:assert(false)<<“ assertion” <<“ failed”;

时间:2018-08-17 08:01:28

标签: c++

我想编写一个像这样的断言函数:

//the following expression outputs "assertion failed" to std::err and then terminates the program
assert(false) << "assertion " << "failed";

到目前为止,我是这样的:

#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";

}

但是我的实现方式仅显示消息“断言”的第一部分。在终止之前,如何打印消息的第二(可能是第三,第四...)部分?

2 个答案:

答案 0 :(得分:3)

不要在每次将某些内容流式传输到对象时检查断言。通过检查并刷新AssertHelper的析构函数,使用对象在语句末尾将被破坏的事实。

您的operator<<应该像这样简单:

AssertHelper& operator<<(const T &v) {
  _message << v;
  return *this;
}

请注意,您返回对同一对象的引用,使对<<的下一次调用流到同一对象!使_message成为一个成员变量,您可以像std::stringstream那样将其流式传输。然后在析构函数中执行以下操作:

~AssertHelper(){
  if(!assert_state){
    std::cerr << _message.str() << std::endl;
    exit(-1);
  }
}

答案 1 :(得分:2)

最小校正:

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);
    }
}

注释:operator<<应该返回引用,而不是值; bool assert_state;可以标记为const;在flush()之后调用<< std::endl是多余的。