Встроенный код при подсчете элементов данных (с использованием шаблонов) - PullRequest
0 голосов
/ 30 июля 2010

Существует простой тип данных POD, такой как

struct Item {
   int value1;
   double value2;
   bool value3;
}

Теперь я хотел бы написать различные функции подсчета, как это можно сделать с помощью следующего кода (или некоторого метода std):

typedef bool Selector(const Item& i);
int count(const vector<Item>& items, Selector f) {
  int sum = 0;
  BOOST_FOREACH(const Item& i, items) {
    if(f(i)) {
      sum++;
    }
  }
  return sum;
}

с f например,

bool someSimpleSelector(const Item& i) {
  return i.value1 > 0; // quite simple criterion
}

Однако при таком подходе компилятор не может встроить вызов функции и, следовательно, не встроит мой (тривиальный) код выбора.

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

Ответы [ 2 ]

2 голосов
/ 30 июля 2010

См. Новые адаптеры диапазона усиления

Selector f;
int count = std::distance(items | boost::range::adaptor::filtered(f));

Подробнее читайте дальше. http://www.boost.org/doc/libs/1_43_0/libs/range/doc/html/range/reference/adaptors/reference/filtered.html

1 голос
/ 30 июля 2010

Замените typedef параметром шаблона, чтобы разрешить универсальные функторы:

template <typename Selector>
int count(const vector<Item>& items, const Selector &f)

Затем замените ваши функции функциональными объектами:

struct someSimpleSelector
{
    bool operator()(const Item& i) const { return i.value1 > 0; }
};

Вы должны обнаружить, что это встроено с подходящими настройками оптимизации компилятора.

Кстати, эту конкретную проблему можно решить с помощью std::count_if().

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...