boost::log的set_filter参数logging::trivial::severity>=info如何转为可调用对象
问题解答
1. 传入参数的实际类型
你代码里的logging::trivial::severity >= logging::trivial::info不是普通的布尔运算表达式,也不是函数指针/lambda,它是Boost.Log基于表达式模板生成的延迟求值表达式对象:
logging::trivial::severity是Boost.Log预定义的日志严重性属性的占位符终端,属于Boost.Phoenix/Boost.Proto表达式框架的实现范畴>=运算符被框架重载,不会立即计算布尔结果,而是会返回一个特化的模板类实例(内部类型一般为boost::log::expressions::aux::greater_equal<...>的实例),用于保存运算的左右操作数、运算规则等信息。
2. 适配为可调用对象的原理
这个表达式对象本身就符合set_filter对可调用参数的要求,适配逻辑分两层:
- 首先,所有Boost.Log表达式模板类型都重载了
operator(),调用签名为bool operator()(const boost::log::attribute_value_set& attrs) const,当日志系统生成新日志记录时,会把当前日志的所有属性传入这个调用运算符,触发表达式的实时求值,返回是否通过过滤的布尔结果,天然符合可调用对象的定义。 - 其次
set_filter内部的m_Filter成员是boost::log::filter类型,这是一个做了类型擦除的包装类,它的赋值运算符可以接收任意符合bool(const attribute_value_set&)签名的可调用对象,自动把传入的表达式模板实例包装成统一的filter类型存储。
你可以简单理解为Boost.Log用表达式模板语法糖帮你自动生成了等效的过滤lambda:
// 你写的表达式和下面的lambda功能完全等效 [] (const logging::attribute_value_set& attrs) -> bool { return attrs.get<logging::trivial::severity_level>("Severity") >= logging::trivial::info; }
内容的提问来源于stack exchange,提问作者Zhang
相关产品推荐
相关产品推荐

