Pull Apart Function Type With Specialized Function

假装没事ソ 提交于 2019-12-01 08:51:57

问题


The answer to this question picks apart a function type using a 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;

As I studied what was being done here I tried to rewrite function_args. I attempted to do this using a function so as to eliminate the need for the decltypeargs template. But found myself mired in improper syntax:

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

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

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


回答1:


//------------------------ 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:


With a function, you can either just reuse the same type trait from before:

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

Or you can reimplement the same with functions. You can't 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:


Functions cannot be specialized like that, but you don't 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;
}


来源:https://stackoverflow.com/questions/38463980/pull-apart-function-type-with-specialized-function

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!