Используя алгоритмы STL, лучше передать указатель функции или функтор?

Выполнение запроса count (*) для больших данных стоит дорого. я думаю, что использование «SELECT * FROM таблицы ORDER BY id ID DESC LIMIT n», где n - это количество строк на странице, лучше и легче

10
задан Gab Royer 22 June 2009 в 14:55
поделиться

6 ответов

Функторы могут (и будут ) тривиально встраиваться - это не делается для обычных указателей на функции.

Таким образом, функторы имеют реальное преимущество в производительности, которое может быть огромная в тугих петлях. Кроме того, функторы, как правило, легче компонуются и, в частности, лучше работают с STL: std :: bind x , например, не работает с указателями функций.

Мне не нравится, как они загромождают код, но, учитывая все преимущества, я бы предпочел их в любое время указателям на функции.

19
ответ дан 3 December 2019 в 13:35
поделиться

Чтобы прояснить неправильное представление о том, что компилятор может встраивать, достаточно хороший компилятор может встраивать указатели на функции. Он может просто встраивать объекты функций с большей легкостью, поскольку доступно больше статической информации. Например, указатель на функцию, которая не принимает параметров и возвращает bool, имеет тип bool (*) (), в то время как функтор имеет явный тип, а именно функтор, и создание экземпляра шаблона может статически вызывать оператор функтора, а не чем вызов через указатель функции.

На практике, однако, в основном это вопрос предоставления компилятору достаточной информации для эффективной оптимизации.

Например, Visual C ++ 2008, учитывая следующий код с полной оптимизацией:

#include "stdafx.h"
#include <algorithm>

const char print_me[]= "hello!";

class print_functor
{
public:
    void operator()(char c)
    {
        printf("%c", c);
    }
};

void print_function(char c)
{
    printf("%c", c);
}

int _tmain(int argc, _TCHAR* argv[])
{
    std::for_each(print_me, print_me + sizeof(print_me)/sizeof(print_me[0]), print_functor());
    printf("\n");

    std::for_each(print_me, print_me + sizeof(print_me)/sizeof(print_me[0]), print_function);

    return 0;
}

полностью встраивает оба вызова std :: for_each . Кстати, на ПК

11
ответ дан 3 December 2019 в 13:35
поделиться

Одним из больших преимуществ объекта функции перед указателем на функцию является то, что вы можете более легко связать некоторые аргументы при построении объекта функции.

Примером функтора, который может это сделать, может быть

  class multiplyBy
  {
  private:
      int m_whatToMultiplyBy;
  public:
      multiplyBy(int whatToMultiplyBy) : 
          m_whatToMultiplyBy(whatToMultiplyBy)
      {
      }

      void operator()(int& i)
      {
          i = m_whatToMultiplyBy * i;
      }
  }


  ...

  // double the array
  for_each(a.begin(), a.end(), multiplyBy(2));

Это «связывание» аргументов может быть выполнено довольно хорошо с помощью boost :: bind и boost :: function если вам доступен буст.

7
ответ дан 3 December 2019 в 13:35
поделиться

Мое мнение - №1 лучше, потому что он проще.

То, что что-то может быть объектом, не означает, что оно должно быть им. Я уверен, что есть случаи, когда функтор имеет смысл, но в большинстве случаев, вероятно, в нем нет необходимости.

6
ответ дан 3 December 2019 в 13:35
поделиться

Функтор может быть более легко встроен , поэтому это может быть фактором, который следует учитывать, когда важна производительность.

1
ответ дан 3 December 2019 в 13:35
поделиться

# 1 проще объявить функцию
а №2 функтор больше похож на вызов функции.

(Иногда приходится отчаяться в синтаксисе C ++)

1
ответ дан 3 December 2019 в 13:35
поделиться
Другие вопросы по тегам:

Похожие вопросы: