Получение возвращаемого типа указателя функции в пакете параметров и сохранение его в виде сцепленного кортежа с другими аргументами - PullRequest
0 голосов
/ 21 января 2019

Я хочу определить тип кортежа на основе переданного пакета параметров, у которого будут все параметры, которые не являются функциями, и вместо тех, которые являются функциями, просто сохраните свой возвращаемый тип.Этот тип будет позже использоваться для индексации в хэш-карте, поэтому мне нужен метод для его получения

std :: result_of кажется решением проблемы, и в моем тестовом коде он работает, если передаются только указатели на функции.Но в моем случае использования можно также передать другие базовые типы, и это выдает «error: нет типа с именем« type »в« class std :: result_of »», хотя я добавил std :: conditional check

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 голосов
/ 21 января 2019

Вы слишком охотно оцениваете метафункцию. Партия 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

...