In C++11 classes cannot deduce all the types of a passed function. But a function can.
So this function can be written:
template<typename Ret, typename Param>
Deduced_Types<Ret, Param> deduce_type(Ret (*)(Param))
{
return Deduced_Types<Ret, Param>();
}
This function uses a type to store the deduced types (it has to be declared before the function):
template<typename Ret, typename Param>
class Deduced_Types
{
public:
typedef Ret Return_type;
typedef Param Parameter_type;
};
Now to test it;
int f(bool)
{
return 0;
}
int main(int argc, char* argv[])
{
decltype( deduce_type(f) )::Return_type i = 0;
return i;
}
It works.
So Now to Bar:
template< class F >
class Bar
{
public:
typedef typename F::Return_type Func_Return_type;
typedef typename F::Parameter_type Fun_Param_type;
};
which has to be called:
Bar< decltype(deduce_type(f)) > b;
(this is where You can use a macro)
Works on gcc 4.8.1 : https://godbolt.org/z/1cz2pk
Edit:
Pre C++17 function could not be passed into a template.
So what is needed is that you need to pass the function pointer into the class. And a static_assert
to verify the parameters are correct:
#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);
}
};
Now instead of passing the function as a template parameter, the function pointer is passed in as a parameter:
void foo(int *p) {}
int *p;
bar b(foo, p);
Only problem here is that the class has to store this pointer for future use.