Having the function definition:
void f(int) { }
I want to define:
int a;
but if the function definition changes to:
void f(double) { }
the variable definition must become:
double a;
that is, the type of "a" must be the same of the first argument of the "f" function. I need something like the following:
decltype_of_argument<f, 0> a;
Is it possible in C++?
The values that are declared within a function when the function is called are known as an argument. These values are considered as the root of the function that needs the arguments while execution, and it is also known as Actual arguments or Actual Parameters.
An argument refers to values that are passed within a function when the calling of a function takes place. Furthermore, specifying argument data types is important for C++ programming. Moreover, C++ supports three types of argument data types – pass by value, pass by reference, and pass by pointer.
In mathematics, an argument of a function is a value provided to obtain the function's result. It is also called an independent variable. , is called a unary function. A function of two or more variables is considered to have a domain consisting of ordered pairs or tuples of argument values.
You can get the type by template metaprogramming:
template <class F> struct ArgType;
template <class R, class T>
struct ArgType<R(*)(T)> {
typedef T type;
};
void f(int) {}
#include <type_traits>
#include <iostream>
int main() {
// To prove
std::cout << std::is_same< ArgType<decltype(&f)>::type, int >::value << '\n';
// To use
ArgType<decltype(&f)>::type a;
}
Depending on where you want to use it you'd need to specialize this litte template for other callable entities such as member function poitners, functions with more arguments, functors etc. There are more sophisitcated approaches in the Boost libraries, see e.g. https://stackoverflow.com/a/15645459/1838266
Caveat: all these utilities work only if the name of the function/callable is unambiguously mapped to one single function signature. If a function is overloaded or if a functor has more than one operator()
, the right function/operator has to be picked by explicitly casting to the right signature, which makes finding out part of the signature via the template pretty useless. This applies in a certain way to templates as well, although getting the signature of an explicitly secialized callable might still be useful, e.g.:
template <unsigned N, class F> struct ArgType; //somewhat more sophisitcated
template <class T> void f(int, T);
ArgType<0, decltype(&f<double>)> //int - ArgType has it's use here
ArgType<1, decltype(&f<double>)> //double - here it's useless...
It depends on what you want to do, where that variable shall be used. If it is in the function a template might be a good choice:
template<typename T>
void foo(T ) {
T a;
}
Alternatively if you are outside the function and have the requirement to really know this you can use Boost.TypeTraits, i.e. function_traits<void (int)>::arg1_type
will give int
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