[Follows up Check boost::log filter explicitly? ]
The following example uses the trivial logger from Boost Log. It outputs 1
, showing that expensive()
is only called once. How does it work? Why is expensive()
not called?
Live On Coliru
#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;
}
Output:
[2018-05-21 14:33:47.327507] [0x00007eff37aa1740] [error] 1
1
It works by using a bit of macro/preprocessor magic. The statements look indeed like a function call to some operator<<()
:
BOOST_LOG_TRIVIAL(warning) << expensive();
However, simplifying a lot, the macro works as if we had written something like:
if (level == warning)
logger << expensive();
If you wanted to simplify that code to avoid writing all the time, you could define a macro like this:
#define LOG_WARNING if (level == warning) logger
And then we could use it as:
LOG_WARNING << expensive();
The actual BOOST_LOG_TRIVIAL
macro ends up expanding into:
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();
As you see, depending on the !!_boost_log_record_N
loop condition (which in turn depends on the result of open_record()
), the body of the loop will be run zero or more times; which is the reason why expensive()
is not always run.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With