我正在尝试编写一个简单的审计类,它通过运算符<<并在收到如下自定义操纵器后写入审核:
class CAudit
{
public:
//needs to be templated
CAudit& operator << ( LPCSTR data ) {
audittext << data;
return *this;
}
//attempted manipulator
static CAudit& write(CAudit& audit) {
//write contents of audittext to audit and clear it
return audit;
}
private:
std::stringstream audittext;
};
//to be used like
CAudit audit;
audit << "Data " << data << " received at " << time << CAudit::write;
我认识到我的代码中的重载运算符不返回流对象,但是想知道是否仍然可以使用类似语法的操作符。目前编译器正在看到'&lt;&lt;&lt;作为二元右移算子。
感谢任何输入, 帕特里克
答案 0 :(得分:4)
要使其工作,您必须添加运算符的重载&lt;&lt;对于功能, 而不是从它调用函数:
class CAudit
{
//...other details here as in original question
CAudit& operator << (CAudit & (*func)(CAudit &))
{
return func(*this);
}
};
CAudit audit;
audit << "some text" << CAudit::write;
答案 1 :(得分:2)
二元移位运算符和流运算符是同一个运算符。重载operator +让你的类在std :: cout上写“Hello world”是完全合法的(尽管这是一个非常糟糕的主意)。与C ++标准作者决定重载运算符&lt;&lt;对于流写入流 你没有写清楚你的问题是什么。我的猜测是编译错误。在这种情况下最好的事情是引用错误消息。如果我是对的,问题是,你只定义了运算符&lt;&lt;对于LPCSTR,然后你希望它在右侧工作功能对象 你使用“操纵者”这个词,但你误解了一些东西。流的操纵器(来自STL的流)是对其写入的流执行某些操作的功能。它只是因为这种过载而起作用:
ostream& operator<< (ostream& ( *pf )(ostream&));
接受一个函数并将其应用于流 同样你需要:
CAudit& operator<< (CAudit& ( *pf )(CAudit& audit))
{
return (*pf)(audit);
}
答案 2 :(得分:1)
不会这个
class CAudit
{
public:
template< typename T >
CAudit& operator<<( const T& data )
{
audittext << data;
return *this;
}
class write {};
void operator<<( const write& data )
{
/* whatever */
}
private:
std::stringstream audittext;
};
做你想做的事?
答案 3 :(得分:1)
我为跟踪做了类似的事情,但使用了stringstream
。这可确保所有第三方operator << ()
和操纵器都能正常工作。我也使用析构函数而不是客户编写操纵器。
class DebugStream
{
public:
DebugStream(short level, const char * file, int line) {
sstream << "L" << level << "\t" << file << "\t" << line << "\t";
}
~DebugStream() { write(sstream.str()); }
std::ostream & stream() { return sstream; }
private:
std::stringstream sstream;
DebugStream(const DebugStream &);
DebugStream & operator=(const DebugStream &);
};
然后可以使用一些宏:
#define DBG_ERROR if (1<=dbg_level()) DebugStream(1, __FILE__, __LINE__).stream()
#define DBG_INFO if (2<=dbg_level()) DebugStream(2, __FILE__, __LINE__).stream()
代码只使用宏
DBG_INFO << "print some debug information";
您不需要特定的写操纵器来将数据刷新到日志文件。当匿名DebugStream
对象超出范围时(一旦控件离开该行),内容将自动写入。
虽然在这种情况下我通常会避免使用宏,但if
语句的使用意味着您没有构建跟踪线的开销,除非您确实需要它。
通过ostream
方法返回stream()
使其能够用于全局成员函数,因为匿名对象不能作为非const引用参数传递。