2

In the question Is it possible to figure out the parameter type and return type of a lambda? a nice implementation of a function_traits struct is shown / linked.

This traits struct allows to determine

  • return type
  • function call type (i.e. R(Ts ...))
  • function arity
  • parameter type for each parameter

However it fails to work properly with default parameters. That is to say, only the complete type (including all default parameters) is considered to be the function's type.

Is it possible to write a function_trait which enables to check whether a given function parameter is a default parameter?


Specifically, I would like to use this trait later using SFINAE to enable / disable a given implementation based on the minimal / maximal arity of a function passed into the function, and the size of the parameter pack passed to the function.

template <typename Func, typename ... Ts>
std::enable_if<(function_trait<decltype(F)>::min_arity >= sizeof ... ( Ts ) 
                and 
                function_trait<decltype(F)>::max_arity <= sizeof ... ( Ts ) )>::type
foo( Func F, Ts ... ts ){
    F( ts ... );
}

Obviously this example is somewhat contrived.

Community
  • 1
  • 1
elemakil
  • 3,681
  • 28
  • 53

1 Answers1

3

You cannot do that with just the function type available, because default arguments are not part of the function type. The following holds:

void foo(int, int);
void bar(int, int = 42);

static_assert(std::is_same<decltype(foo), decltype(bar)>::value, "He's wrong!");

This means you cannot say whether a function of type Func can be called with a certain number of arguments less than its number of parameters.

Angew is no longer proud of SO
  • 167,307
  • 17
  • 350
  • 455
  • This implies that whenever I go via a function pointer/reference, the default arguments won't work anymore (they become mandatory), right? I mean like `auto bar2 = bar;` – leemes Jan 16 '15 at 13:13
  • 1
    Correct. Default arguments are only relevant at immediate call sites. – Sebastian Redl Jan 16 '15 at 13:19
  • @SebastianRedl Thanks for clarifying. I just tested: [it's even not possible when forwarded via template parameters](http://ideone.com/bkXnN9), that's kinda sad. – leemes Jan 16 '15 at 13:23