我想编写一个像这样的断言函数:
//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";
}
但是我的实现方式仅显示消息“断言”的第一部分。在终止之前,如何打印消息的第二(可能是第三,第四...)部分?
答案 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
是多余的。