c ++ 11获取第一个(第二个,等等)参数的类型,类似于result_of [英] c++11 get type of first (second, etc...) argument, similar to result_of

查看:151
本文介绍了c ++ 11获取第一个(第二个,等等)参数的类型,类似于result_of的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

假设我有一个模板函数,该函数带有一个参数,它是一个函数(可以是std :: function或lambda或实际的函数指针)。一个愚蠢的例子说明了这个问题:

Let's suppose I have a template function which takes an argument, which is a function (it can be a std::function, or a lambda, or actual function pointer). A silly example that illustrates the problem:

template<typename F,typename A,typename B = typename std::result_of<F(A)>::type>
B blabla(F &&f)
{
    return f(A())/3;
}

我可以使用std :: result_of :: typename引用f的返回类型,因为我具有A的类型,但我希望编译器从F的第一个参数推导出类型A。
(如果我写

I can reference the return type of f with std::result_of::typename, given I have the type of A, but I would like the compiler to deduce type A from F's first argument. (If I write

template<typename A,typename B>
B blabla(const std::function<B(A)> &f)
{
    return f(A())/3;
}

编译器在推导A和B时会遇到问题(特别是如果它不是std :: function而是lambda时),所以这不是正确的方法。 )

the compiler have problems deducing A and B (especially if it's not an std::function but a lambda), so this is not the right way to do it.)

推荐答案

这不适用于其运算符为的通用lambda或任意仿函数已超载或为模板。

This won't work for generic lambdas or arbitrary functors whose operator() is overloaded or is a template.

// primary template.
template<class T>
struct function_traits : function_traits<decltype(&T::operator())> {
};

// partial specialization for function type
template<class R, class... Args>
struct function_traits<R(Args...)> {
    using result_type = R;
    using argument_types = std::tuple<Args...>;
};

// partial specialization for function pointer
template<class R, class... Args>
struct function_traits<R (*)(Args...)> {
    using result_type = R;
    using argument_types = std::tuple<Args...>;
};

// partial specialization for std::function
template<class R, class... Args>
struct function_traits<std::function<R(Args...)>> {
    using result_type = R;
    using argument_types = std::tuple<Args...>;
};

// partial specialization for pointer-to-member-function (i.e., operator()'s)
template<class T, class R, class... Args>
struct function_traits<R (T::*)(Args...)> {
    using result_type = R;
    using argument_types = std::tuple<Args...>;
};

template<class T, class R, class... Args>
struct function_traits<R (T::*)(Args...) const> {
    using result_type = R;
    using argument_types = std::tuple<Args...>;
};

// additional cv-qualifier and ref-qualifier combinations omitted
// sprinkle with C-style variadics if desired

然后

template<class T>
using first_argument_type = typename std::tuple_element<0, typename function_traits<T>::argument_types>::type;

根据需要将0替换为所需的数字,或者编写一个单独的别名并使用一个索引。 演示

Replace 0 with the desired number as needed, or write a separate alias that also take an index. Demo.

这篇关于c ++ 11获取第一个(第二个,等等)参数的类型,类似于result_of的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆