Pull Apart Function type with specialized function

The answer to this question highlights the type of function using the class template:

template <typename T> struct function_args {}; template <typename R, typename... Args> struct function_args<R(Args...)> { using type = tuple<Args...>; }; template <typename T> using decltypeargs = typename function_args<T>::type; 

When I learned what is being done here, I tried to rewrite function_args . I tried to do this using a function to eliminate the need for a decltypeargs template. But it turned out that I was mired in the wrong syntax:

 template <typename T> tuple<> myTry(); template <typename Ret, typename... Args> tuple<Args...> myTry<Ret(Args...)>(); 

Strike>

My hope was to call decltype(myTry<decltype(foo)>()) to get the tuple type instead of calling decltypeargs<decltype(foo)> . Is there any way to do this with function declaration?

+2
c ++ templates metaprogramming template-function
source share
3 answers
 //------------------------ Machinery: #include <tuple> template< class Ret, class... Args > std::tuple<Args...> m( Ret(Args...) ); //------------------------- Example: #include <iostream> #include <typeinfo> void foo( double ); using namespace std; auto main() -> int { using Args_tuple = decltype( m( foo ) ); cout << typeid( Args_tuple ).name() << endl; } 
+2
source share

Using the function, you can either reuse the same type trait earlier:

 template <typename T> function_args<T> myTry(); 

Or you can override them using functions. You cannot partially specialize function templates, but you can overload:

 namespace detail { template <class T> struct tag { }; template <class R, class... Args> tag<std::tuple<R, Args...>> myTry(tag<R(Args...)> ); template <class R, class C, class... Args> tag<std::tuple<R, Args...>> myTry(tag<R(C::*)(Args...)> ); // etc. } template <typename T> auto myTry() { return detail::myTry(detail::tag<T>{}); } 
+3
source share

Functions may not be so specialized, but you do not need to specialize a function for this. Tested with gcc 6.1.1:

 #include <iostream> #include <tuple> template <typename T> struct my_try; template <typename Ret, typename... Args> struct my_try<Ret(Args...)> { std::tuple<Args...> operator()(); }; template<typename T> auto MyTry() { return my_try<T>()(); } void foo(int, char); int main() { decltype(MyTry<decltype(foo)>()) t; int *a= &std::get<0>(t); char *b= &std::get<1>(t); return 0; } 
+1
source share

All Articles