2012-01-31 3 views
3

Это является продолжение на How do I get the argument types of a function pointer in a variadic template class?Используя неконстантное выражение в качестве параметра шаблона

Я имею эту структуру, чтобы получить доступ аргументов в VARIADIC шаблона:

template<typename T> 
struct function_traits; 

template<typename R, typename ...Args> 
struct function_traits<std::function<R(Args...)>> 
{ 
    static const size_t nargs = sizeof...(Args); 

    typedef R result_type; 

    template <size_t i> 
    struct arg 
    { 
     typedef typename std::tuple_element<i, std::tuple<Args...>>::type type; 
    }; 
}; 

И доступ к типу аргумента of Args с

typedef function<void(Args...)> fun; 
std::cout << std::is_same<int, typename function_traits<fun>::template arg<0>::type>::value << std::endl; 

Однако, я хотел бы повторить аргументы, чтобы иметь возможность обрабатывать произвольное количество аргументов. Ниже не работает, но, чтобы проиллюстрировать то, что я хочу:

for (int i = 0; i < typename function_traits<fun>::nargs ; i++){ 
    std::cout << std::is_same<int, typename function_traits<fun>::template arg<i>::type>::value << std::endl; 
} 

ответ

5

Вы должны были бы сделать во время компиляции итерации по линии

template <typename fun, size_t i> struct print_helper { 
    static void print() { 
     print_helper<fun, i-1>::print(); 
     std::cout << std::is_same<int, typename function_traits<fun>::template arg<i-1>::type>::value << std::endl; 
    } 
}; 

template <typename fun> struct print_helper<fun,0> { 
    static void print() {} 
}; 

template <typename fun> void print() { 
    print_helper<fun, function_traits<fun>::nargs>::print(); 
} 
+0

Спасибо @ Mike. Я решил, что он должен быть рекурсивным и во время компиляции мне просто не удалось собрать его;) НО: 'fun' неизвестно в области. Я попытался передать 'fun' в качестве параметра шаблона, но в специализации компилятор жалуется, что« функция частичной специализации шаблона »печатает <0, fun>« не разрешено ». Моя специализация гласит: 'template void print <0,fun>() {}' – steffen

+0

@steffen: Нет, вы не можете частично специализировать шаблоны функций, только шаблоны классов. Думаю, вам нужно будет обернуть функции в классах; Я обновлю ответ. –

+0

Красивое, идеальное решение! Спасибо! – steffen

Смежные вопросы