我有一个 struct
喜欢
struct log {
boost::mutex mut;
std::stringstream a_stringstream;
//...
};
在我的代码中我有一个 vector 并且经常这样做
{
boost::lock_guard <boost::mutex> lock(logs[AN_ENUM].mut);
logs[AN_ENUM].a_stringstream << "something" << a_double << a_string << etc;
}
每次我想记录一些东西时,都要有锁卫和括号似乎很冗长。起初我想也许我可以重载 <<
我的结构的运算符,但我读到了它,但我认为这行不通。有什么好的方法可以将其压缩为方法调用吗?
最佳答案
您可以创建一个可变参数模板函数(例如 log_it
),它采用 AN_ENUM
加上要记录的可变数量的项目,锁定 mutex
一次,然后将所有内容流式传输到 a_stringstream
。例如:
#include <mutex>
#include <sstream>
#include <vector>
class save_stream
{
std::ostream& os_;
char fill_;
std::ios::fmtflags flags_;
std::streamsize precision_;
public:
~save_stream()
{
os_.fill(fill_);
os_.flags(flags_);
os_.precision(precision_);
}
save_stream(const save_stream&) = delete;
save_stream& operator=(const save_stream&) = delete;
explicit save_stream(std::ostream& os)
: os_(os)
, fill_(os.fill())
, flags_(os.flags())
, precision_(os.precision())
{}
};
struct log
{
std::mutex mut;
std::stringstream a_stringstream;
};
std::vector<log> logs(10);
enum : std::size_t {AN_ENUM};
void
log_one(std::size_t)
{
}
template <class Arg0, class ...Args>
void
log_one(std::size_t log, Arg0 const& arg0, Args const& ...args)
{
logs[log].a_stringstream << arg0;
log_one(log, args...);
}
template <class ...Args>
void
log_it(std::size_t log, Args const& ...args)
{
std::lock_guard<std::mutex> lock(logs[log].mut);
save_stream s{logs[log].a_stringstream};
logs[log].a_stringstream << "log " << log << " says : ";
log_one(log, args...);
logs[log].a_stringstream << '\n';
}
这不是大量的代码。 log_it
接受一个整数常量,使用它索引到 logs
中以锁定互斥量,吐出前缀字符串,然后调用 log_one
常量日志索引和可变数量的注销参数。
log_one
然后简单地记录第一个参数,然后对包的其余部分递归调用 log_one
。
可以这样使用:
log_it(AN_ENUM, std::fixed, std::setprecision(3), "i = ", 4.5);
log_it(AN_ENUM, "j = ", 4.5);
这导致 logs[0].a_stringstream
持有:
log 0 says : i = 4.500
log 0 says : j = 4.5
我敢肯定语法可以被精炼成更漂亮的东西,但这得到了基本的想法:传递可变数量的参数,锁定在调用堆栈的顶部,然后一个一个地处理每个参数。
“日志级别”可能只是 log_it
的另一个参数。
关于c++ - 如何用方法调用替换 `{ lock_guard lock(obj.mut); obj.a_stringstream << a << b/*...*/<< n;}`,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36109710/