我有struct
喜欢
struct log {
boost::mutex mut;
std::stringstream a_stringstream;
//...
};
在我的代码中我有一个向量,经常做
{
boost::lock_guard <boost::mutex> lock(logs[AN_ENUM].mut);
logs[AN_ENUM].a_stringstream << "something" << a_double << a_string << etc;
}
每次我想要记录某些内容时,都要使用锁定装置和支架。起初我想也许我可能会为我的结构重载<<
运算符,但我读到它并且我认为它不起作用。有没有一种方法可以将其压缩为方法调用?
答案 0 :(得分:4)
您可以创建一个可变参数模板函数(比如log_it
),它将AN_ENUM
加上可变数量的项目进行记录,锁定mutex
一次,然后将所有内容流式传输到{{ 1}}。例如:
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
我确信语法可以更精细到更漂亮的东西,但是这得到了基本的想法:传递可变数量的args,锁定在调用堆栈的顶部,然后逐个处理每个arg。
“日志级别”可能只是log 0 says : i = 4.500
log 0 says : j = 4.5
的另一个参数。
答案 1 :(得分:0)
我想不出为什么这个模板重载&lt;&lt;会员不会工作:
template<typename param>
auto operator<<(param &&Param)
{
boost::lock_guard <boost::mutex> lock(mut);
a_stringstream << std::forward<param>(Param);
return *this;
}
我不知道你读到的内容可能暗示这种方法不起作用,但无论你读什么,都是错的。我的例子可能需要一些调整,这里和那里,取决于你的实际类,但理论上它应该是非常可行的。