Здесь я даю C ++ 11 обновление для @ BjörnPollex (правильный) ответ.
Возвращаясь к вопросу, вы хотите явно указать второй аргумент doIt
, главным образом, для ограничения того, что можно передать. В C ++ 11 вы можете подразумевать это ограничение, не зная явно тип аргумента функтора (который не очень хорошо определен, если функтор все равно перегружен).
template < typename FunctorType, class ArgumentType >
auto doIt( FunctorType functor, ArgumentType arg ) -> decltype(bool(functor(arg)))
{
return functor( arg );
}
(преобразование в bool
может даже не понадобиться, я поместил его здесь, потому что кажется, что вы действительно хотите, чтобы возвращаемый тип был bool
).
Эта doIt
(шаблонная) функция будет принимать любой аргумент, который, возможно, совместим с аргументом functor
(и также может быть преобразован в bool
). Если переданный аргумент несовместим, функция вообще не будет существовать и выдаст изящную ошибку компилятора «doIt function not found».
Можно сделать еще один шаг, используя совершенную перемотку вперед, чтобы сделать doIt
в точности эквивалентным functor(arg)
:
template < typename F, class A >
auto doIt( F&& f, A&& a ) -> decltype(bool(std::forward<F>(f)(std::forward<A>(a))))
{
return std::forward<F>(f)( std::forward<A>(a) );
}