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