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??
Comments
-
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 wantargCount
to be 3.void foo(int a, int b, int c) {} int main() { size_t argCount = MAGIC(foo); }
-
SergeyA about 8 yearsThere is a way to do this.
-
SergeyA about 8 yearsToo complicated :) see my answer for a shorted example.
-
Ven about 8 yearsThe fact you can do it doesn't mean it makes sense, however. But yes, you're correct.
-
SergeyA about 8 yearsIt makes perfect sence in many applications of template metaprogramming.
-
R Sahu about 8 years@SergeyA, thanks for the prod. It's now more simplified than your answer :)
-
SergeyA about 8 yearsSo 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 about 8 years@RSahu Prefer to just return an
integral_constant
thansize_t
(see Columbo's answer on the dupe) -
R Sahu about 8 years@Barry, my understanding of
integral_constant
being used in the dupe is to simplify the implementation ofstruct 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 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 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 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 about 7 yearsWhy 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 over 4 yearsHow can we make this work also for member functions ?
-
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 over 4 yearsMaybe do something like this: gcc.godbolt.org/z/4NWT_N