В C ++ 11 классы не могут определить все типы переданной функции. Но функция может.
Таким образом, эта функция может быть написана:
template<typename Ret, typename Param>
Deduced_Types<Ret, Param> deduce_type(Ret (*)(Param))
{
return Deduced_Types<Ret, Param>();
}
Эта функция использует тип для хранения выведенных типов (она должна быть объявлена перед функцией):
template<typename Ret, typename Param>
class Deduced_Types
{
public:
typedef Ret Return_type;
typedef Param Parameter_type;
};
Теперь, чтобы проверить это;
int f(bool)
{
return 0;
}
int main(int argc, char* argv[])
{
decltype( deduce_type(f) )::Return_type i = 0;
return i;
}
Работает.
Итак, теперь Бар:
template< class F >
class Bar
{
public:
typedef typename F::Return_type Func_Return_type;
typedef typename F::Parameter_type Fun_Param_type;
};
который должен называться:
Bar< decltype(deduce_type(f)) > b;
(здесь вы можете использовать макрос)
Работает на gcc 4.8.1: https://godbolt.org/z/1cz2pk
Edit:
Предварительно функция C ++ 17 не может быть передана в шаблон.
Итак, вам нужно передать указатель на функцию в класс. И static_assert
для проверки правильности параметров:
#include <type_traits>
struct bar
{
template<typename F, typename T>
bar(F f, T t)
{
typedef decltype(deduce_type(f)) D;
static_assert(std::is_same<typename D::Parameter_type, T>::value,"parameter has different type function parameter");
f(t);
}
};
Теперь вместо передачи функции в качестве параметра шаблона указатель функции передается в качестве параметра:
void foo(int *p) {}
int *p;
bar b(foo, p);
Единственная проблема здесь в том, что класс должен хранить этот указатель для будущего использования.