2015-05-28 3 views
2

Есть ли способ в C++ для итерации по типам параметров функции во время компиляции? Я хочу сделать что-то вроде этого:Итерации над типами функций функции во время компиляции

struct null_type {}; 

float foo(int, bool, char); 

get_param_type<foo, 0>::type float_var; // return type 
get_param_type<foo, 1>::type int_var; // first arg type 
get_param_type<foo, 2>::type bool_var; // second arg type 
get_param_type<foo, 3>::type char_var; // third arg type 
get_param_type<foo, 4>::type null_type_var; 
+1

Boost MPL на помощь! –

+0

@buttifulbuttefly: 20k loc и 4GB RAM позже ... :-) –

ответ

3

Вы можете легко написать это самостоятельно. Во-первых, пакет типы параметров функции в кортеж:

#include <tuple> 

template <typename> struct FnArgs; 

template <typename R, typename ...Args> 
struct FnArgs<R(Args...)> 
{ 
    using type = std::tuple<Args...>; 
}; 

Теперь вы можете использовать стандартный кортеж API для доступа к элементам:

using FT = FnArgs<decltype(foo)>::type; 

std::tuple_element<0, FT> x; 

Еще специализации для указателей на член-функция легко добавляется, если вам это нужно.

(Вы не можете легко обойти decltype, так как нет типа вычета для параметров шаблона нетиповых (пока).)

+0

[demo] (https://ideone.com/hljGVV) –

+0

Это выглядит хорошо для меня, но я пытаюсь избавиться от decltype .. – ivaigult

+0

@ivaigult: Как я уже сказал, я считаю, что это невозможно с помощью шаблонов. Вы не можете иметь параметры без шаблона без указания их типа. (Вы можете написать макрос, если хотите.) –

2

Вот версия, которая использует свой null_type для недоступных индексов:

template <typename, std::size_t, typename = void> 
struct get_param_type 
{ 
    using type = null_type; 
}; 

template <typename Ret, typename... Args, std::size_t N> 
struct get_param_type<Ret(Args...), N, std::enable_if_t<N < (1+sizeof...(Args))>> 
{ 
    using type = typename std::tuple_element<N,std::tuple<Ret,Args...>>::type; 
}; 
Смежные вопросы