Лучший способ (с точки зрения производительности) передать оператор сравнения в качестве аргумента в c ++ - PullRequest
0 голосов
/ 02 апреля 2020

Рассмотрим следующий шаблон функции, который принимает вектор input и value и находит элементы, которые превышают это значение, и возвращает индекс этих элементов через output:

template <typename T>
void findGreater(const vector<T>& input, const T& value, vector<size_t>& output){
  output.resize(input.size());
  typename vector<T>::const_iterator inp = input.begin();
  vector<size_t>::iterator out = output.begin();
  size_t s = 0;
  for (size_t i; i<input.size(); i++, inp++)
    if (*inp > value)  //<------------------------
      *(out++)=i;
  output.resize(std::distance(output.begin(),out));
}

Теперь я нахожу для реализации ту же функцию для других операций, а именно: findGreaterEqual, findLess и findLessEqual. Я думал о создании функции шаблона, очень похожей на приведенную выше, которая принимает дополнительный аргумент compare, как показано ниже, и реализует строку, показанную с помощью // <--------------------- ---, как <code>if (compare(inp,value)).

template <typename T, typename COMP>
void findGreater(const vector<T>& input, const T& value, vector<size_t>& output, const COMP& compare)

Теперь я могу передавать различные вещи как compare, например, из STL (std :: большее, ect), лямбда-функции, функции, объекта класса который реализует operator ().

Вопрос в том, какой выбор лучше с точки зрения производительности? И есть ли другой лучший способ сделать это?

Большое спасибо.

1 Ответ

1 голос
/ 02 апреля 2020

Большинство компиляторов генерируют точно так же.

Если бы у вас была шаблонная функция, которая брала функтор, для каждого типа должна была бы быть создана новая функция. Если типом был std::less, std::greater или какой-то лямбда-тип без захвата, очень просто оптимизировать встроенный вызов operator(). Даже с более сложным функтором, таким как захват лямбда-типа или структура с членами данных, вставка, вероятно, все равно будет выполнена.

То, что вы делаете, создавая несколько функций findGreater и findLess, по сути «создание экземпляра вручную» шаблона.

Пример встраивания

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