Given the type of a callable function C
, I want to get at compile time a std::function
; the type of which:
- has the same return type of function
C
- the argument types are the first
N
argument types of functionC
This means that, for a given type void(int, char, double)
and a given N
, the type of the function is:
N = 1
=> result type:std::function<void(int)>
N = 2
=> result type:std::function<void(int, char)>
N = 3
=> result type:std::function<void(int, char, double)>
N > 3
=> compile time error
Example:
template<std::size_t N, typename R, typename... A>
constexpr auto get() {
return /*(magically somehow)*/ std::function<R(FirstNFromA...)>
}
template<std::size_t N, typename R, typename... A>
struct S {
using func = decltype(get<N, R, A...>());
};
It follows a possible solution:
The basic idea is to use a
tuple
and those utilities that are part of the Standard template Library (as an example,std::tuple_element
), mix them with a pack expansion placed in the right place and that's all.To do that, I used a
constexpr
function that returns an emptystd::function
object of the given type. Then the type of the function is taken by means of adecltype
and exported as a type of theFuncType
object using an alias.Everything takes place at compile time.
In order to deduce the right type for that function, I used a well known pattern that involves a
std::integer_sequence
and actually unpack the types of a tuple by expanding the indexes.As I mentioned in the comments, if such problem arises then my first approach would be to change the problem itself! Sometimes, instead of finding a "tough solution" for a "tough problem", it's better to make the problem itself "simpler"!
There should never be a need, where one has to write
FuncType<2, R(X,Y,Z)>::type
instead of simplestd::function<R(X,Y)>
.Above is my real answer. To solve your problem as a coding delight, I am putting a simple macro based answer. Instead of compile time, it will give you the required type at preprocessing time.
Usage:
As you can see there is a little change in usage. Instead of
FuncType<2, void(int, char, double, int)>::type
, I am usingFuncType(2, void, int, char, double, int)
. Here is the demo.As of now, the
FUNC_N
macros are overloaded upto 3 arguments. For more arguments, if we want to avoid copy pastes, then we can generate a header file with a simple program:And simply
#include
it:Here is the demo for how to generate the header file.
Another tuple based solution.
Should work with C++11 too.
I suppose it can be simplified but I don't know how to avoid the use of the
bool
template parameter (I'm just learning C++11).p.s.: sorry for my bad English.
Another solution could be:
Edit: Yet another maybe a little bit simpler (that does not need a std::tuple) solution: