请考虑以下 Boost.Accumulator 示例,其中 value_type
是整数类型:
typedef boost::accumulators::features <
boost::accumulators::tag::sum
, boost::accumulators::tag::min
, boost::accumulators::tag::max
, boost::accumulators::tag::mean
> Features;
typedef boost::accumulators::accumulator_set <
value_type
, Features
> Accumulator;
但是,从accumulator_set
中提取值对于min
、max
和sum
是有意义的,并且返回类型是明确的。(accu
是一个变量(的类型呢:
boost::accumulator::extract_result < tag::mean > ( accu );
我想类型是double
.类型是如何推断的?
我的兴趣被激起了,所以我在 boost 源代码中遵循了它。
我创建了一个value_type = int的累加器。extract_result的结果确实是双重的。
这是在extract_result<>中通过以下行推断出来的:
typename mpl::apply<AccumulatorSet, Feature>::type::result_type
这反过来又取决于这一行:
typedef typename numeric::functional::fdiv<Sample, std::size_t>::result_type result_type;
(其中样本是整数(
这里部分专门用于在除法时将整数强制为双精度:
// partial specialization that promotes the arguments to double for
// integral division.
template<typename Left, typename Right>
struct fdiv_base<Left, Right, typename enable_if<are_integral<Left, Right> >::type>
: functional::divides<double const, double const>
{};
示例程序:
#include <iostream>
#include <typeinfo>
#include <boost/accumulators/accumulators.hpp>
#include <boost/accumulators/statistics.hpp>
typedef boost::accumulators::features <
boost::accumulators::tag::sum
, boost::accumulators::tag::min
, boost::accumulators::tag::max
, boost::accumulators::tag::mean
> Features;
typedef boost::accumulators::accumulator_set <
int
, Features
> Accumulator;
using namespace std;
int main()
{
Accumulator acc;
acc(0);
acc(99);
auto mean = boost::accumulators::extract_result < boost::accumulators::tag::mean > (acc);
cout << "mean is " << mean << " of type " << typeid(mean).name() << endl;
}
编辑:
检查:
typename mpl::apply<AccumulatorSet, Feature>::type::result_type
AccumulatorSet
是我们的累加器(从论证推导出extract_result
( Feature
tag::mean
tag::mean
出口impl
这是一个impl::mean_impl<mpl::_1, sum>
extract_result
函数调用find_accumulator<Feature>(acc)
,返回对mpl::apply<Feature>::type
(将累加器作为参数的函数对象(的引用
在这个对象上调用 result(( 调用 mean 的 impl(_1(,其中 _1 是 sum(累加器(,mean_impl可以从中提取sample_type,其中它用于 fdiv<> 参数的类型推断。
不幸的是,模板元函数很难写,甚至更难阅读!