我正在编写一些算法来构建随机森林,每个森林都会 使用单独的函数训练单独的数据(每个树将使用一组 具有固定签名的函数,但是将使用不同的树来训练 不同的功能集可以有不同的签名),但是我 我想用编写代码来构建随机树一次 模板。我目前有以下内容:
模板类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's)不仅要接受 TrainingDataPoint(模板类型T)但是数据缓存。这样我的功能 指针看起来像:
typedef double (*function_ptr)(TrainingDataPoint&,
unordered_map<string, cv::Mat>& preloaded_images);
现在问题是,我想不出一种方法来保持RandomTree类的通用性 但是有一些功能集(模板类型V)不仅仅需要 训练点(模板类型T)。
到目前为止,我已经想过:
这些选项似乎都不是特别吸引我,希望有人可以提供一些经验并告诉我更好的方法吗?
由于
答案 0 :(得分:4)
使用仿函数来处理需要状态的函数。 C ++中的仿函数是一个带有重载operator()的类(或结构),因此仿函数的一个实例可以“被称为”函数。 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)是上面的标准库版本,并且写得更好。
答案 1 :(得分:0)
是否可以向随机树中添加另一个参数以接收缓存。如果未提供,则默认为空缓存。例如
template<typename T, typename V, typename CacheDataType = EmptyCache>
class RandomTree{ ... }
RandomTree<TrainingDataPoint, function_ptr, ProloadedImageCache>