获取参数包中函数指针的返回类型,并将其保存为与其他args串联的元组

时间:2019-01-21 01:44:31

标签: c++ templates tuples c++14 variadic

我想基于传递的参数包定义一个元组类型,该参数包将具有非函数的所有参数,并代替那些是函数的参数,只保存其返回类型。该类型将稍后在哈希映射中用于索引,因此我需要一种获取它的方法

std :: result_of似乎是解决问题的方法,在我的测试代码中,如果仅传递函数指针,则它可以工作。但是在我的用例中,即使我添加了std :: conditional check

,也可能会传递其他基本类型,并且抛出“错误:在'class std :: result_of'中没有名为'type'的类型”
template <typename ...Args>
using tuple_cat_t = decltype(std::tuple_cat(std::declval<Args>()...));

template <typename ...Args>
void eval(Args... args) {
    using tuple_t = std::tuple<Args...>;
    using pattern_t = tuple_cat_t<
        typename std::conditional <
        std::is_pointer<Args>::value && std::is_function<typename std::remove_pointer<Args>::type>::value,
        std::tuple < std::result_of_t<Args&&()> > ,
        std::tuple<Args>
        >::type...
    >;
}

int fn(){ return 5; }   
int main(){
    eval(fn,fn); //all good, pattern type is std::tuple<int, int>
    eval(5,fn); //comilation error
}

1 个答案:

答案 0 :(得分:2)

您正在急切地评估元功能。 result_of部分也被评估为int

您应该重新排列条件,以使您选择的是元函数而不是类型,然后求值:

template <typename T> struct identity { using type = T; };

template <typename Arg>
using maybe_eval = typename std::conditional_t<
    std::is_pointer<Arg>::value && std::is_function<typename std::remove_pointer<Arg>::type>::value,
    std::result_of<Arg&&()>,
    identity<Arg>
    >::type;

using pattern_t = tuple_cat_t<std::tuple<maybe_eval<Args>>...>;

请注意,我同时使用 conditional_t type