Get function parameters count

10,498

Solution 1

You can get that information by using a variadic function template.

#include <iostream>

template <typename R, typename ... Types> constexpr size_t getArgumentCount( R(*f)(Types ...))
{
   return sizeof...(Types);
}

//----------------------------------    
// Test it out with a few functions.
//----------------------------------    

void foo(int a, int b, int c)
{
}

int bar()
{
   return 0;
}

int baz(double)
{
   return 0;
}

int main()
{
    std::cout << getArgumentCount(foo) << std::endl;
    std::cout << getArgumentCount(bar) << std::endl;
    std::cout << getArgumentCount(baz) << std::endl;
    return 0;
}

Output:

3
0
1

See it working at http://ideone.com/oqF8E8.

Update

Barry suggested use of:

template <typename R, typename ... Types> 
constexpr std::integral_constant<unsigned, sizeof ...(Types)> getArgumentCount( R(*f)(Types ...))
{
   return std::integral_constant<unsigned, sizeof ...(Types)>{};
}

With this, you can get the number of argument by using:

// Guaranteed to be evaluated at compile time
size_t count = decltype(getArgumentCount(foo))::value;

or

// Most likely evaluated at compile time
size_t count = getArgumentCount(foo).value;

Solution 2

Yes, it can be easily done:

#include <cstddef>
#include <iostream>

template <class R, class... ARGS>
struct function_ripper {
    static constexpr size_t n_args = sizeof...(ARGS);
};


template <class R, class... ARGS>
auto constexpr make_ripper(R (ARGS...) ) {
  return function_ripper<R, ARGS...>();
}

void foo(int, double, const char*);

void check_args() {
  constexpr size_t foo_args = decltype(make_ripper(foo))::n_args;

  std::cout << "Foo has  " << foo_args << " arguments.\n";
}

Solution 3

This doesn't really make sense for several reasons.

For starters, what would this really be good for? You might be looking for some sort of reflection, but that doesn't (yet) exist in C++.

The main reason this doesn't make sense, however, is overload sets:

void f(int);
void f(int, int);
std::cout << MAGIC(f); // what should this print??
Share:
10,498
Mayhem
Author by

Mayhem

I'm Batman!

Updated on June 30, 2022

Comments

  • Mayhem
    Mayhem almost 2 years

    I'm wondering if there is a way in C++11 to get the number of arguments of a function?

    For example for the function foo I want argCount to be 3.

    void foo(int a, int b, int c) {}
    
    int main() {
      size_t argCount = MAGIC(foo);
    }
    
  • SergeyA
    SergeyA about 8 years
    There is a way to do this.
  • SergeyA
    SergeyA about 8 years
    Too complicated :) see my answer for a shorted example.
  • Ven
    Ven about 8 years
    The fact you can do it doesn't mean it makes sense, however. But yes, you're correct.
  • SergeyA
    SergeyA about 8 years
    It makes perfect sence in many applications of template metaprogramming.
  • R Sahu
    R Sahu about 8 years
    @SergeyA, thanks for the prod. It's now more simplified than your answer :)
  • SergeyA
    SergeyA about 8 years
    So very much true! :) The only thing is, mine doesn't call a function, while yours does. You need to make yours constexpr, but this would still be no guarantee of it never being called - this is why I prefer my version. However, yours have simpler code.
  • Barry
    Barry about 8 years
    @RSahu Prefer to just return an integral_constant than size_t (see Columbo's answer on the dupe)
  • R Sahu
    R Sahu about 8 years
    @Barry, my understanding of integral_constant being used in the dupe is to simplify the implementation of struct get_arity. For a free function, such as I presented here, that won't add any extra value. Please let me know if I am missing something subtle.
  • Barry
    Barry about 8 years
    @RSahu It adds extra value from the perspective of encoding the answer in a type. It's always easy to go type --> value, but keeping everything on the type level just makes metaprogramming easier. Plus, you can then just pass this into another function and overload on different arity.
  • R Sahu
    R Sahu about 8 years
    @SergeyA, Yes, making the function a constexpr definitely makes sense, regardless of whether the compiler translates that into a compile time evaluation or a run time call.
  • R Sahu
    R Sahu about 8 years
    @Barry, I still don't quite grasp the value of your suggestion. I'm going need some time to mull over it. Thanks for the input.
  • paulm
    paulm about 7 years
    Why say it makes no sense when you don't even know what the use case is? This is exactly what is required for binding stack based scripting language native calls, you need the argument count.
  • Muhammet Ali Asan
    Muhammet Ali Asan over 4 years
    How can we make this work also for member functions ?
  • R Sahu
    R Sahu over 4 years
    @MuhammetAliAsan, that's a good question. If that has not been asked in SO, please create a post and ask it. You can add a link to this post from your post, just to provide some context.
  • Ayxan Haqverdili
    Ayxan Haqverdili over 4 years
    Maybe do something like this: gcc.godbolt.org/z/4NWT_N