Templates and generic programming
T.40
Используйте функциональные объекты для передачи операций алгоритмам
Причина
Функциональные объекты могут передавать через интерфейс больше информации, чем «обычный» указатель на функцию. В целом передача функциональных объектов даёт лучшую производительность, чем передача указателей на функции.
Пример
bool greater(double x, double y) { return x > y; }
sort(v, greater); // указатель на функцию: потенциально медленно
sort(v, [](double x, double y) { return x > y; }); // функциональный объект
sort(v, std::greater{}); // функциональный объект
bool greater_than_7(double x) { return x > 7; }
auto x = find_if(v, greater_than_7); // указатель на функцию: негибко
auto y = find_if(v, [](double x) { return x > 7; }); // функциональный объект: несёт нужные данные
auto z = find_if(v, Greater_than<double>(7)); // функциональный объект: несёт нужные данные
Конечно, эти функции можно обобщить с помощью auto или концептов. Например:
auto y1 = find_if(v, [](totally_ordered auto x) { return x > 7; }); // требуем упорядоченный тип
auto z1 = find_if(v, [](auto x) { return x > 7; }); // надеемся, что тип имеет >
Примечание
Лямбды порождают функциональные объекты.
Примечание
Аргумент о производительности зависит от компилятора и технологии оптимизатора.
Контроль
- Помечать указатели на функции как аргументы шаблона.
- Помечать указатели на функции, передаваемые как аргументы шаблону (риск ложных срабатываний).