Я заинтересован в написании исходного кода для нескольких компиляторов (GCC, MSVC, Clang).Я видел два шаблона для передачи функций в качестве аргументов времени компиляции, и мне любопытно, являются ли компиляторы, как правило, достаточно умными, чтобы признать, что они эквивалентны, или я слишком много спрашиваю.Вот стиль STL, передающий объект функтор:
template<class InputIterator, class Predicate>
InputIterator find_if ( InputIterator first, InputIterator last, Predicate pred )
{
for ( ; first!=last ; first++ ) if ( pred(*first) ) break;
return first;
}
А вот альтернативный стиль:
template<class InputIterator, class Predicate, class PredData>
InputIterator find_if ( InputIterator first, InputIterator last, PredData data )
{
for ( ; first!=last ; first++ ) if ( Predicate::eval(*first, data) ) break;
return first;
}
В стиле STL ваш класс Predicate обычно содержит в качестве членов любые данные, которые ему нужныи вы вызываете operator () для оценки предиката.В альтернативном стиле у вас никогда нет объекта Predicate, скорее он содержит статический метод, который принимает проверяемый элемент, и данные передаются в качестве аргумента, а не сохраняются в качестве члена в Predicate.
Iесть несколько опасений, использующих стиль STL:
- Если предикат - слово или меньше, будет ли компилятор достаточно умен, чтобы передать его регистром?В альтернативном стиле слово будет аргументом, поэтому компилятору не нужно ничего выводить.
- Если предикат пуст, будет ли он достаточно умен, чтобы избежать его создания и передачи?В альтернативном стиле Predicate никогда не создается.
Так что моя интуиция заключается в том, что альтернативный стиль должен быть быстрее, но, возможно, я недооцениваю современных оптимизаторов.