У меня есть эта проблема (гистограммирование).У меня есть реальное пространство: [a,b]
каким-то образом разделено ([a0=a, a1, a2, ..., b]
).Разделение может быть с равным пространством (a1 - a0 = a2 - a1 = ...
) или переменными.
Мне нужен класс, который обрабатывает это, с некоторыми методами, чтобы сказать, учитывая значение, к которому принадлежит элемент bin раздела;другие методы, чтобы найти центр определенной корзины и многое другое.
Во время программы я не люблю создавать экземпляр класса только для вызова таких простых функций, как
Binner binner(binning);
binner.get_bin(1.3);
binner.get_centerbin(2);
, поэтому я попыталсянаписать статический класс, используя шаблон, чтобы сделать что-то подобное:
Binner<binning>::get_bin(1.3);
Binner<binning>::get_centerbin(2);
Это хорошая идея?Есть другой способ сделать это?Теперь у меня есть бесплатные функции, такие как
double get_bin(double bin, Binning binning); // a lot of if/else inside
, но я думаю, что это слишком подвержено ошибкам.
Вот моя реализация:
enum Binning {CELL, LARGE, BE};
const double binning_LARGE[] = {0, 1.2, 1.425, 1.550, 1.800, 2.5};
const double binning_BE[] = {0, 1.425, 1.550, 2.5};
template<Binning binning>
class Binner
{
public:
static const double* bins;
static const int n;
static int get_bin(double value);
};
template<> const double* myclass<LARGE>::bins = binning_LARGE;
template<> const double* myclass<BE>::bins = binning_BE;
template<> const int myclass<LARGE>::n = sizeof(binning_LARGE) / sizeof(double);
template<> const int myclass<BE>::n = sizeof(binning_BE) / sizeof(double);
template<Binning binning> int myclass<binning>::get_bin(double value)
{
return find_if(bins, bins + n,
bind2nd(greater<double>(), value)) - bins - 1;
}
template<> int myclass<CELL>::get_bin(double value)
{
return static_cast<int>(value / 0.025);
}
- это хорошореализация / дизайн?
- Есть ли способ избежать использования поля
n
с помощью std::vector
?Как? Есть ли способ параметризации 0.025
?Я знаю, что double
не может быть параметром шаблона, но я могу написать что-то похожее на это:
Binner<0.025> binner;
- other / advices?
Редактировать:
Третий пункт. Почему я не могу этого сделать:
template<Binning binning, int N=100>
class Binner
{
public:
static const double* bins;
static const int n;
static int bin(double value);
};
...
template<Binning binning, int N> int Binner<CELL, N>::bin(double value)
{
return static_cast<int>(value / (2.5 / N));
}