C ++: как использовать мой код шаблона

Я пишу несколько алгоритмов для построения случайных лесов, каждый лес будет
обучены на отдельных данных с отдельными функциями (каждое дерево будет использовать набор
функции с фиксированной сигнатурой, однако различные деревья будут обучаться с использованием
разные наборы функций, которые могут иметь разные сигнатуры), однако я
хотел бы просто написать код для построения случайных деревьев один раз, используя
шаблоны. В настоящее время у меня есть что-то вроде следующего:

класс T шаблона соответствует типу обучающих данных (например, патч изображения или
пиксель) шаблон класса V соответствует типу указателя функции

template<class T, class V>
class RandomTree{

void build(RandomTreeNode<T>& current_node,
vector<V>& functions,
vector<T>& data) {
... some code that basically calls a function passing in data T
}
}

и я создаю объект так:

typedef double (*function_ptr)(TrainingDataPoint& data_point);

RandomTree<TrainingDataPoint, function_ptr> tree = ...

Проблема в том, что по причинам эффективности для одного из деревьев я
сборка, я хочу, чтобы набор функций (function_ptr) принимал не только
TrainingDataPoint (тип шаблона T), но кэш данных. Так что моя функция
указатель будет выглядеть так:

typedef double (*function_ptr)(TrainingDataPoint&,
unordered_map<string, cv::Mat>& preloaded_images);

Теперь проблема в том, что я не могу придумать, как сохранить класс RandomTree универсальным
но есть некоторые наборы функций (шаблон типа V), которые занимают больше, чем просто
тренировочный пункт (тип шаблона Т).

До сих пор я думал о:

  1. Создание глобального кэша, чтобы функции могли получить к нему доступ
  2. добавление указателя на кэш для каждой точки данных обучения (но кто отвечает за очистку?)
  3. Добавление третьего параметра шаблона в RandomTree, но в этом случае, если я создаю дерево, для которого не требуется этот третий параметр, что мне туда добавить?

Ни один из этих вариантов не кажется мне особенно привлекательным, надеюсь, кто-то может поделиться своим опытом и рассказать мне о лучшем способе?

Спасибо

1

Решение

Используйте функтор для функций, которым нужно состояние. Функтор в C ++ — это класс (или структура) с перегруженным оператором (), так что экземпляр функтора можно «вызвать как» функцию. Аргументами функтора в RandomTree должны быть именно те параметры, которые меняются и находятся под контролем RandomTree, остальные должны быть связаны снаружи. Пример функтора с дополнительным состоянием, которое оборачивает функцию:

template<typename Retval, typename Arg1, typename ExtraData>
struct BindExtraData
{
typedef Retval(*func_type)(Arg1, ExtraData);
BindExtraData( ExtraData const& d_, func_type func_ ):d(d_), func(func_) {};
ExtraData d;
func_type func;
Retval operator()( Arg1 a1 )
{
return func(a1, d);
}
};

но вы можете сделать лучше. Если это одноразовый, нет необходимости делать его шаблоном. bind2nd (ну, binder2nd) — это стандартная версия библиотеки выше, и она будет лучше написана.

4

Другие решения

Можете ли вы добавить еще один параметр в RandomTree, который принимает кэш. По умолчанию будет пустой кеш, если не указан. Например

template<typename T, typename V, typename CacheDataType = EmptyCache>
class RandomTree{ ... }

RandomTree<TrainingDataPoint, function_ptr, ProloadedImageCache>
0

По вопросам рекламы [email protected]