C ++:如何重用我的模板代码

时间:2012-10-25 14:57:57

标签: c++ templates machine-learning function-pointers random-forest

我正在编写一些算法来构建随机森林,每个森林都会 使用单独的函数训练单独的数据(每个树将使用一组 具有固定签名的函数,但是将使用不同的树来训练 不同的功能集可以有不同的签名),但是我 我想用编写代码来构建随机树一次 模板。我目前有以下内容:

模板类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)。

到目前为止,我已经想过:

  1. 使缓存全局化,以便函数可以访问它
  2. 向每个训练数据点添加一个指向缓存的指针(但谁负责清理?)
  3. 向RandomTree添加第三个模板参数,但在这种情况下,如果我正在构建一个不需要此第三个参数的树,我该放哪个?
  4. 这些选项似乎都不是特别吸引我,希望有人可以提供一些经验并告诉我更好的方法吗?

    由于

2 个答案:

答案 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>