所以我使用了Log class:
#include <stdio.h>
#include <iostream>
class Log
{
public:
int i;
Log()
{
i = 0;
}
template <class T>
Log &operator<<(const T &v)
{
i++;
std::cout << i << ":" << v << ";" <<std::endl;
return *this;
}
Log &operator<<(std::ostream&(*f)(std::ostream&))
{
i++;
std::cout << i << ":" << *f << ";" <<std::endl;
return *this;
}
~Log()
{
std::cout << " [end of message]" << std::endl;
}
};
我用的是:
#include <log.h>
int main()
{
Log a;
a << "here's a message" << std::endl;
a << "here's one with a number: " << 5;
std::cin.get();
}
我希望我的日志类在我放“;”时得到意思是如果我有a << "here's a message" << std::endl;
我希望它能够得到它是oune日志消息而a << "here's one with a number: " << 5;
是另一个。
它会输出下一条消息:
1:here's a message;
2:
;
3:here's one with a number: ;
4:5;
我想保留其sintax(无限数量的<<
,大范围的值类型,api中没有(
和)
,但要输出:
1:here's a message
;
2:here's one with a number: 5;
怎么做这样的事情?
答案 0 :(得分:5)
让operator<<
返回一个临时值,该值会在销毁时放置endl
并将所有operator<<
次调用转发给主对象。这样,endl
可以保证只调用一次。
class Log
{
struct EndlOnDeath {
Log* log;
EndlOnDeath(Log* ptr)
: log(ptr) {}
template<typename T> EndlOnDeath& operator<<(const T& val) {
(*log) << val;
}
~EndlOnDeath() {
(*log) << std::endl;
}
};
public:
int i;
Log()
{
i = 0;
}
template <class T>
EndlOnDeath operator<<(const T &v)
{
i++;
std::cout << i << ":" << v << ";";
return this;
}
Log &operator<<(std::ostream&(*f)(std::ostream&))
{
i++;
std::cout << i << ":" << *f << ";" <<std::endl;
return *this;
}
~Log()
{
std::cout << " [end of message]" << std::endl;
}
};
答案 1 :(得分:2)
您可以定义一个特殊对象,插入后会指示日志条目的结束。我知道这不是你想要的,但它很容易实现。它还使您可以灵活地将日志条目分布在多个语句中(例如,这对于在循环中生成日志条目的一部分非常有用)。
struct LogEnd {};
const LogEnd logend;
class Log
{
public:
Log() : number_(0) {}
template <typename T> Log& operator<<(const T& x)
{
ss_ << x;
}
Log& operator<<(const LogEnd& aLogEnd)
{
// Dump the stringstream string to output with desired decorations.
std::cout << number_ << ": " << ss_.str() << std::endl;
// Clear the stringstream
ss_.str("");
++number_;
}
private:
std::ostringstream ss_;
int number_;
};
int main()
{
Log log;
log << "This is " << 1 << " log entry" << logend;
}