2

这个问题的答案使用类模板挑选出一个函数类型:

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;

当我研究这里正在做的事情时,我试图重写function_args. 我试图使用一个函数来做到这一点,以消除对decltypeargs模板的需求。但发现自己陷入了不正确的语法:

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

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

我的希望是打电话decltype(myTry<decltype(foo)>())来获取tuple类型,而不是打电话decltypeargs<decltype(foo)>。有没有办法通过函数声明来做到这一点?

4

3 回答 3

3

使用函数,您可以重用以前的相同类型特征:

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

或者您可以使用函数重新实现相同的功能。您不能部分专门化函数模板,但可以重载:

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>{}); }
于 2016-07-19T16:54:05.957 回答
2
//------------------------ 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;
}
于 2016-07-19T17:21:45.603 回答
1

函数不能像那样专门化,但您不需要为此专门化函数。使用 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;
}
于 2016-07-19T16:45:24.300 回答