2015-07-11 2 views
4

Я искал некоторые из исходных кодов Boost и заметил, что они реализуют шаблонные функции с помощью функтора вместо простой функции? Для этого есть причина?Функционалы шаблонов против функций

Например:

template<typename Foo, typename Bar> 
struct functor { 
    Bar operator()(const Foo& foo) { 
     return foo.as_bar(); 
    } 
}; 

в противоположность:

template<typename Foo, typename Bar> 
Bar func(const Foo& foo) { 
    return foo.as_bar(); 
} 

Единственное преимущество, что я могу придумать это позволяет классам наследовать функцию?

ответ

2

Есть две основные причины: во-первых, как отмечала пифоническая метафора, частичная специализация действительна только для классов, а не для функций. Обратите внимание, что функции могут использовать перегрузки для решения этой проблемы в целом, но часто, если вы выполняете метапрограммирование, проще и более универсально использовать частичную специализацию. На самом деле я думаю, что это была главная причина.

Вторая причина заключается в том, что в любое время, когда код хочет принять объект функции (например, в STL, например std :: transform), он будет иметь параметр шаблона типа. Если вы передадите функтор или лямбда, точный тип известен во время компиляции, и вы не платите за косвенность, и может быть сделана вставка. Если вы передадите указатель на функцию (или std :: function), во время компиляции будет известна только подпись, и вы платите за косвенность (и вы не можете встроить). Например, std :: sort может быть значительно быстрее с функтором, чем указателем на функцию.

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

+0

Специфика того, что я искал, - это способ определения переходов между цветовыми пространствами, поэтому я бы предположил, что действительно разрешить частичную специализацию. Однако, из того, что я прочитал. Кажется, что использование функтора всегда является лучшим выбором? – maddisoj

+0

Всегда очень сильный термин. Где вы это читали? У функторов есть свои преимущества, но они также более подробные. Как правило, перегрузки также легче рассуждать, чем частичные специализации. Лично я бы начал с функций и использовал функторы только в том случае, если у меня была потребность, основанная на общем программировании или производительности. Boost делает много общего программирования и должен быть более осторожным с соображениями производительности, поскольку они являются широко используемой библиотекой. Сложность реализации - это наименее важный атрибут для них. Ваша (и моя) ситуация обычно различна. –

+0

Всегда был мой собственный вывод. Спасибо за ваше объяснение. – maddisoj

Смежные вопросы