Let's say I have the following function declaration:
template<typename signature>
int foo();
Given the above-mentioned function, is it possible to define foo
in such a way, so that it returns the number of function arguments that were passed in the decltype
template parameter?
So the example usage might look like:
int bar(int a, int b)
{
return a + b;
}
int jar(int a)
{
return a * a;
}
int main()
{
std::cout << foo<decltype(bar)>() << std::endl; // Desired output: 2
std::cout << foo<decltype(jar)>() << std::endl; // Desired output: 1
}
Thanks, everyone for the replies. They do seem to work. However, I forgot to mention one more use case.
Let's say I want to get the number of arguments of the following function:
int __stdcall car(int a, int b, int c)
{
return a * b + c;
}
The answers so far do not seem to work with this kind of function that uses __stdcall
convention.
Any idea why and what can be done about it?
For that(i.e. with decltype
), the given foo
is not enough. You need something like the followings traits.
template<typename> struct funtion_args final {};
template<typename ReType, typename... Args>
struct funtion_args<ReType(Args...)> final
{
static constexpr std::size_t noArgs = sizeof...(Args);
};
Used sizeof...
operator on the variadic template arguments, to get the no of arguments.
And then you can get the argument count directly like
std::cout << funtion_args<decltype(bar)>::noArgs << "\n"; // output: 2
or pack into the foo
template<typename signature>
constexpr std::size_t foo() noexcept
{
return funtion_args<signature>::noArgs;
}
(See Live Demo)
If you want less typing(i.e. without decltype
), a more convenient way of getting the arguments count of a free-function, you could do the following
template <typename ReType, typename... Args>
constexpr auto foo(ReType(*)(Args...)) noexcept
{
return sizeof...(Args);
}
Now you could conveniently call the foo
with other functions as arguments
std::cout << foo(bar) << "\n"; // output: 2
(See Live Demo)
Sure, just have foo()
call on a suitable trait type. For example:
template <typename T>
struct foo_helper;
template <typename T, typename... Args>
struct foo_helper<T(Args...)> {
static constexpr std::size_t arg_count = sizeof...(Args);
};
template <typename T>
std::size_t foo() {
return foo_helper<T>::arg_count;
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With