下面代码的目标是实现一个直方图,其中桶限制是模板参数:
#include <iostream>
#include <limits>
#include "histogram.h"
int main ( int argc, char* argv[] )
{
//histogram_tuple<5,10,15,std::numeric_limits<int>::max()> histogram;
histogram_tuple<5,10,15> histogram;
histogram.count ( 9 );
histogram.count ( 10 );
histogram.count ( 11 );
histogram.count ( 15 );
std::cout << sizeof ( histogram ) << std::endl;
std::cout << '<' << histogram.limit() << ' ' << histogram.count() << ", "
<< '<' << histogram.rest().limit() << ' ' << histogram.rest().count() << ", "
<< '<' << histogram.rest().rest().limit() << ' ' << histogram.rest().rest().count() << ", "
<< ' ' << histogram.rest().rest().rest().count()
<< std::endl;
std::cout << "====" << std::endl;
std::cout << '<' << bucket_limit<0>(histogram) << ':'
<< bucket_count<0>(histogram) << std::endl;
std::cout << '<' << bucket_limit<1>(histogram) << ':'
<< bucket_count<1>(histogram) << std::endl;
std::cout << '<' << bucket_limit<2>(histogram) << ':'
<< bucket_count<2>(histogram) << std::endl;
// std::cout << '<' << bucket_limit<3>(histogram) << ':'
// << bucket_count<3>(histogram) << std::endl;
}
以上工作正常。通过重复的 rest() 调用,最终存储桶的计数(值 >= 15)被打印出来。
但是,当 main() 的最后一行未注释时,g++ 4.7.1 会生成一个编译器错误,即 bucket_limit_entry<0u> 和 bucket_count_entry<0u> 不完整。
关于如何让便利函数 bucket_limit<3> 编译的任何建议,因为重复的 rest() 调用有效?
不太清楚发生了什么。将索引类型更改为 int 并使终止案例 -1 而不是 0 不起作用。
这是直方图.h:
#pragma once
template <int ... Limits>
class histogram_tuple;
template<>
class histogram_tuple<>
{
int cnt_;
public:
histogram_tuple<>() :
cnt_ ( 0 )
{
}
void count ( int value )
{
++cnt_;
}
int count() const
{
return cnt_;
}
};
template <int First, int ... Rest>
class histogram_tuple <First,Rest...> :
private histogram_tuple<Rest...>
{
static const int limit_ = First;
int cnt_;
public:
histogram_tuple <First,Rest...>() :
cnt_ ( 0 )
{ }
int limit() const { return limit_; }
void count ( int value )
{
if ( value < limit_ )
++cnt_;
else
rest().count ( value );
}
int count() const
{
return cnt_;
}
const histogram_tuple<Rest...>& rest() const
{
return *this;
}
histogram_tuple<Rest...>& rest()
{
return *this;
}
};
template <unsigned index, int ... Limits>
struct bucket_count_entry;
template <int First, int ... Limits>
struct bucket_count_entry<0,First,Limits...>
{
static int value(histogram_tuple<First,Limits...> const& histogram)
{
return histogram.count();
}
};
template <unsigned index,int First, int ... Limits>
struct bucket_count_entry<index,First,Limits...>
{
static int value(histogram_tuple<First,Limits...> const& histogram)
{
return bucket_count_entry<index-1,Limits...>::value(histogram.rest());
}
};
template <unsigned index,int ... Limits>
int bucket_count( histogram_tuple<Limits...> const& histogram )
{
return bucket_count_entry<index,Limits...>::value(histogram);
}
template <unsigned index, int ... Limits>
struct bucket_limit_entry;
template <int First, int ... Limits>
struct bucket_limit_entry<0,First,Limits...>
{
static int value(histogram_tuple<First,Limits...> const& histogram)
{
return histogram.limit();
}
};
template <unsigned index,int First, int ... Limits>
struct bucket_limit_entry<index,First,Limits...>
{
static int value(histogram_tuple<First,Limits...> const& histogram)
{
return bucket_limit_entry<index-1,Limits...>::value(histogram.rest());
}
};
template <unsigned index,int ... Limits>
int bucket_limit( histogram_tuple<Limits...> const& histogram )
{
return bucket_limit_entry<index,Limits...>::value(histogram);
}