Для указателей на функции, вы можете просто пользователь, введите подпись:
template<class F, class T>
void foo(F f, T x){
f(x);
}
void bar(int){}
void bar(double){}
int main(){
foo<void(int)>(bar, 5);
}
Live example on Ideone.
foo
будет void foo(void f(int), int x)
после замены, то же самое, что и foo(void (*f)(int), int x)
. Это обеспечивает так называемый «контекст вызова», который позволяет компилятору выбрать правильную перегрузку. Очевидно, что это работает только хорошо, если первым параметром шаблона является функция. Чтобы обойти это ограничение, и сделать его лучше (имхо, по крайней мере), вы можете предоставить простую вспомогательную функцию:
template<class F>
auto get_overload(F f) -> decltype(f) { return f; }
На самом деле, вы можете только перегрузку типов параметров, но вы не можете отбраковать из необходимо, чтобы пользователь вводил тип возвращаемого значения, так как это снова отключает вызывающий контекст, поскольку тип должен быть выведен.
Поскольку вы, скорее всего (или, конечно) только хочу, чтобы это для указателей на функции, вы можете изменить его к этому:
template<class F>
F* get_overload(F* f){ return f; }
Это еще совсем то же самое. Единственная причина, почему первая версия не может иметь только F
, так как тип возврата - F
- void(int)
, если вы вызываете его с помощью get_overload<void(int)>(bar)
, а стандарт не позволяет вам возвращать функции (да, это тип функции). Функция для преобразования указателя функции (void(int)
->void(*)(int)
) часть только для параметров.
Так по какой причине @VJovic удалил свой ответ, я просто изменить это:
Вы можете использовать простой лямбда вместо функции get_overload
. Он будет примерно одинаковым характером длины и намного более удобным и понятным. Он также будет более эффективным, так как не задействованы никакие (функциональные) указатели, и компилятор вполне способен встроить вызов.
foo([](int i){ return bar(i); }, 5);
'static_cast' - одна из альтернатив, хотя явно менее идеальная. – ildjarn
Что значит «грех» не работает? Он компилирует штраф –
@VJovic: Что значит, что я имею в виду? Он не компилируется. Однако ваш удаленный ответ. Я не знаю почему. – user2023370