Reputation: 6340
Is there a good way to grab the argument and return types from a std::function
such that we also return the cv and reference qualifiers? This partially relates to a previous question here. In any case, using the code in the answer, we have the following example:
#include <functional>
#include <iostream>
template<typename T>
struct function_traits;
template<typename R, typename ...Args>
struct function_traits<std::function<R(Args...)>> {
static const size_t nargs = sizeof...(Args);
typedef R result_type;
template <size_t i>
struct arg {
typedef typename std::tuple_element<i, std::tuple<Args...>>::type
type;
};
};
template <typename T>
void foo(T const & f) {
typedef function_traits <T> stuff;
std::cout <<
typeid(typename function_traits <T>::result_type).name()
<< std::endl;
std::cout <<
typeid(typename function_traits <T>::template arg<0>::type).name()
<< std::endl;
std::cout << typeid(T).name() << std::endl;
}
int main() {
std::cout << "Function: f" << std::endl;
auto f = [](double x) { return x+1.;};
foo <std::function<double(double)>> (f);
std::cout << std::endl << "Function: g" << std::endl;
auto g = [](double const & x) { return x+1.;};
foo <std::function<double(double const &)>> (g);
}
Now, using c++filt, we see the type of f
is std::function<double (double)>
and the type of g
is std::function<double (double const&)>
. However, the structure function_traits
reports the argument types to be the same, which they are not. Basically, the const&
was stripped off the argument type for g
. Is there a way to fix this so that const&
is retained?
Upvotes: 1
Views: 93
Reputation: 72421
The const
and reference are stripped off by typeid
, not by function_traits
. Try adding
std::cout << std::boolalpha << std::is_same<double,
typename function_traits<T>::template arg<0>::type>::value << std::endl;
std::cout << std::boolalpha << std::is_same<const double&,
typename function_traits<T>::template arg<0>::type>::value << std::endl;
to your foo
and you'll see the expected values.
Upvotes: 5