9

I have the following problem:

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 */ ) >;

  // ...
}

I want to get the result type of callable which takes sizeof...(N_i) many arguments of the type T as its input, e.g., callable(1,2,3) in case of T==int and sizeof...(N_i)==3. How can this be implemented?

Many thanks in advance.

abraham_hilbert
  • 2,221
  • 1
  • 13
  • 30
  • 3
    Maybe looking at [`std::integer_sequence`](http://en.cppreference.com/w/cpp/utility/integer_sequence) will be helpful. – NathanOliver Oct 26 '16 at 17:33

3 Answers3

12

We can use a type alias to hook onto the expansion of N_i, but always give back 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>...) >;

  // ...
}
Quentin
  • 62,093
  • 7
  • 131
  • 191
6

You could write the following helpers

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>{}));

then in your foo you'd write

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

live demo

krzaq
  • 16,240
  • 4
  • 46
  • 61
6

Why not simply use:

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

you could also use a trick borrowed from Columbo's answer:

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

or even:

using callable_out_type =  std::result_of_t< callable(std::enable_if_t<(N_i, true), T>...) >;
Community
  • 1
  • 1
W.F.
  • 13,888
  • 2
  • 34
  • 81