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);
}
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);
}
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;
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";
}
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??