2016-10-26 5 views
9

У меня есть следующая проблема:Создание последовательности типа T во время компиляции

template< typename callable, typename T , size_t... N_i> 
void foo() 
{ 
    using callable_out_type = std::result_of_t< callable(/* T , ... , T <- sizeof...(N_i) many */) >; 

    // ... 
} 

Я хочу, чтобы получить тип результата callable который принимает sizeof...(N_i) много аргументов типа T в качестве входных данных, например, callable(1,2,3) в случае T==int и sizeof...(N_i)==3. Как это можно реализовать?

Большое спасибо заранее.

+3

Может быть, глядя на [ 'станд :: integer_sequence'] (Http: //en.cppreference. com/w/cpp/utility/integer_sequence). – NathanOliver

ответ

6

Почему бы не просто использовать:

using callable_out_type = std::result_of_t< callable(decltype(N_i, std::declval<T>())...) >; 

вы также можете использовать трюк заимствованные из Columbo's answer:

using callable_out_type = std::result_of_t< callable(std::tuple_element_t<(N_i, 0), std::tuple<T>>...) >; 

или даже:

using callable_out_type = std::result_of_t< callable(std::enable_if_t<(N_i, true), T>...) >; 
12

Мы можем использовать псевдоним типа, чтобы подключиться к расширению N_i, но всегда возвращаем T.

template <class T, std::size_t> 
using eat_int = T; 

template< typename callable, typename T , size_t... N_i> 
void foo() 
{ 
    using callable_out_type = std::result_of_t< callable(eat_int<T, N_i>...) >; 

    // ... 
} 
5

Вы можете написать следующие Помощники с

template<typename T, size_t> 
using type_t = T; 

template<typename Callable, typename T, size_t... Is> 
auto get_result_of(std::index_sequence<Is...>) -> std::result_of_t<Callable(type_t<T,Is>...)>; 

template<typename Callable, typename T, size_t N> 
using result_of_n_elements = decltype(get_result_of<Callable, T>(std::make_index_sequence<N>{})); 

тогда в вашем foo вы написали бы

template< typename callable, typename T , size_t N> 
void foo() 
{ 
    using callable_out_type = result_of_n_elements<callable, T, N>; 
} 

live demo

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