如何正确设计一个从结构中获取不同字段的仿函数

时间:2013-07-04 06:37:24

标签: c++ functor

我有std::vectorstruct个包含多个字段的内容,如下所示:

struct stats
{
   double mean;
   double median;
   double rms;
};
std::vector<stats> data;

我想设计一个在vector上运行的函数,例如,构建一个直方图。我希望能够指定此功能应该运行的struct s的字段。例如:

build_histogram(data, get_mean);
build_histogram(data, get_median);
build_histogram(data, get_rms);

我尝试在stats类中实现一些getter,如下所示:

struct stats
{
   double mean;
   double median;
   double rms;
   struct get_mean { double operator() () { return mean; };
   struct get_median { double operator() () { return median; };
   struct get_rms { double operator() () { return rms; };
};

但它表示对非静态成员meanmedianrms的使用无效。 我怎么能正确实现它?

2 个答案:

答案 0 :(得分:4)

您正在尝试传递类型而不是对象。在迭代容器时,仿函数应该接受vector元素作为参数。有几种方法可以做到这一点,与您尝试做的最相似的是:

struct stats
{
   double mean;
   double median;
   double rms;
   struct get_mean { double operator() (const stats& s) { return s.mean; } };
   struct get_median { double operator() (const stats& s) { return s.median; } };
   struct get_rms { double operator() (const stats& s) { return s.rms; } };
};

build_histogram(data, stats::get_mean());
build_histogram(data, stats::get_median());
build_histogram(data, stats::get_rms());

但是如果你支持lambdas(C ++ 11中的新功能),那么使用它们会更简单。

struct stats
{
   double mean;
   double median;
   double rms;
};

build_histogram(data, [](const stats& s) { return s.mean; });
// etc.

要使其中任何一个工作,build_histogram应该是一个函数模板,第二个参数是任何可调用对象(根据需要更改ReturnType)。

template <typename F>
ReturnType build_histogram(const std::vector<stats>& data, F functor)
{
     // here you can use functor() or pass it to STL algorithm (e.g. find_if)
}

定义仿函数的不同方法是(或多或少按照我的偏好顺序)

  • lambda function(C ++ 11)
  • 免费功能
  • 仿函数对象(这是你所做的,但它不必嵌套在类型中)
  • 静态成员函数
  • 使用std::bind的成员函数(我不建议这样做)

答案 1 :(得分:0)

为什么重新发明元组?

enum {mean, median, rms};
typedef std::tuple<double,double,double>  stats;
stats   st{1,2,3};
cout << get<mean>(st);
相关问题