Boost Log 的普通记录器 "lazy evaluation" 是如何工作的?
How does the "lazy evaluation" of Boost Log's trivial loggers work?
[跟进 明确检查 boost::log 过滤器?
]
以下示例使用来自 Boost Log 的普通记录器。它输出 1
,表明 expensive()
只被调用了一次。它是如何工作的?为什么 expensive()
没有被调用?
#include <iostream>
#include <boost/log/expressions.hpp>
#include <boost/log/trivial.hpp>
int count = 0;
int expensive()
{
return ++count;
}
int main()
{
boost::log::core::get()->set_filter(
boost::log::trivial::severity >= boost::log::trivial::warning
);
BOOST_LOG_TRIVIAL(error) << expensive();
BOOST_LOG_TRIVIAL(info) << expensive();
std::cout << count << '\n';
return 0;
}
输出:
[2018-05-21 14:33:47.327507] [0x00007eff37aa1740] [error] 1
1
它通过使用一些 macro/preprocessor 魔法来工作。这些语句看起来确实像是对某些 operator<<()
:
的函数调用
BOOST_LOG_TRIVIAL(warning) << expensive();
然而,简化了很多,宏的工作方式就好像我们写了这样的东西:
if (level == warning)
logger << expensive();
如果您想简化该代码以避免一直编写,您可以定义一个这样的宏:
#define LOG_WARNING if (level == warning) logger
然后我们可以将其用作:
LOG_WARNING << expensive();
实际的 BOOST_LOG_TRIVIAL
宏最终扩展为:
for (
::boost::log::record _boost_log_record_N =
(::boost::log::trivial::logger::get()).open_record(
(::boost::log::keywords::severity = ::boost::log::trivial::error)
)
;
!!_boost_log_record_N;
)
::boost::log::aux::make_record_pump(
(::boost::log::trivial::logger::get()),
_boost_log_record_N
).stream() << expensive();
如您所见,根据 !!_boost_log_record_N
循环条件(这又取决于 open_record()
的结果),循环体将是 运行 零个或多个次;这就是为什么 expensive()
并不总是 运行.
的原因
[跟进 明确检查 boost::log 过滤器? ]
以下示例使用来自 Boost Log 的普通记录器。它输出 1
,表明 expensive()
只被调用了一次。它是如何工作的?为什么 expensive()
没有被调用?
#include <iostream>
#include <boost/log/expressions.hpp>
#include <boost/log/trivial.hpp>
int count = 0;
int expensive()
{
return ++count;
}
int main()
{
boost::log::core::get()->set_filter(
boost::log::trivial::severity >= boost::log::trivial::warning
);
BOOST_LOG_TRIVIAL(error) << expensive();
BOOST_LOG_TRIVIAL(info) << expensive();
std::cout << count << '\n';
return 0;
}
输出:
[2018-05-21 14:33:47.327507] [0x00007eff37aa1740] [error] 1
1
它通过使用一些 macro/preprocessor 魔法来工作。这些语句看起来确实像是对某些 operator<<()
:
BOOST_LOG_TRIVIAL(warning) << expensive();
然而,简化了很多,宏的工作方式就好像我们写了这样的东西:
if (level == warning)
logger << expensive();
如果您想简化该代码以避免一直编写,您可以定义一个这样的宏:
#define LOG_WARNING if (level == warning) logger
然后我们可以将其用作:
LOG_WARNING << expensive();
实际的 BOOST_LOG_TRIVIAL
宏最终扩展为:
for (
::boost::log::record _boost_log_record_N =
(::boost::log::trivial::logger::get()).open_record(
(::boost::log::keywords::severity = ::boost::log::trivial::error)
)
;
!!_boost_log_record_N;
)
::boost::log::aux::make_record_pump(
(::boost::log::trivial::logger::get()),
_boost_log_record_N
).stream() << expensive();
如您所见,根据 !!_boost_log_record_N
循环条件(这又取决于 open_record()
的结果),循环体将是 运行 零个或多个次;这就是为什么 expensive()
并不总是 运行.