2

I have a std::vector of structs that contain several fields, like the following:

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

I'd like to design a function that operates on the vector, for example, builds a histogram. I'd like to be able to specify what filed of the structs should this function operate on. For example:

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

I tried to implement some getters in the stats class, like this:

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; };
};

But it says that's an invalid use of non-static members mean, median and rms. How could I implement it correctly?

4

2 回答 2

4

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

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 函数 (C++11)
  • 自由功能
  • 仿函数对象(这是您所做的,但不必嵌套在类型中)
  • 静态成员函数
  • 成员函数使用std::bind(我不建议这样做)
于 2013-07-04T06:43:07.950 回答
0

为什么要重新发明元组?

enum {mean, median, rms};
typedef std::tuple<double,double,double>  stats;
stats   st{1,2,3};
cout << get<mean>(st);
于 2013-07-04T06:51:35.183 回答