Confused with a simple mix of templates and non-type functions that return a tuple

As an exercise, I am trying to write 2 simple functions that take the non-type int N pattern. First, I need to create a tuple of N copies of some object of type T. I would like it to resemble the following:

template <class T, int N> 
constexpr std::tuple<T...> fun(T t) {
  return (N > 0) ? std::tuple_cat(t, fun<T, N-1>(t)) : std::make_tuple(t);
}

      

I have also tried something like this without success ( http://liveworkspace.org/code/3LZ0Fe ). I would like to be able to create an instance with T = bool, say:

auto bools = fun<bool, 10> (false);

      

The second should be a small change; I have a templated structure Foo and I would like to create a tuple containing Foo <0>, ..., Foo <N>

template <int N> struct Foo {
   static const int id = N;
}

template <template <int> class T, int N> 
constexpr ??? fun2 (???) {...}

      

Since templated functions cannot be partially specialized, I don't even know how to write the correct completion for my recursion. I would like to do this completely statically, without using for loops.

=============================================== === ================================

Following Seth's suggestion, I got stuck writing the fun function itself, which repeated endlessly:

template<typename T, int N>
typename fun_helper<T, N>::type 
fun(T t) {
  if (N > 0) 
    return typename fun_helper<T, N>::type 
      { std::tuple_cat(std::make_tuple(t), fun<T, N-1>(t)) };
  else return typename fun_helper<T, N>::type { };
}

      

Using an additional structure with completion, I was able to get this working:

template<typename T, int N> struct fun {
  typename fun_helper<T, N>::type make(T t) {
    return typename fun_helper<T, N>::type 
      { std::tuple_cat(std::make_tuple(t), fun<T, N-1>().make(t)) };
  }
};

template<typename T> struct fun<T, 0> {
  typename fun_helper<T, 0>::type 
  make(T t) {
    return typename fun_helper<T, 0>::type { };
  }
};

      

The call is still relatively clunky:

auto conds = fun<bool, 3>().make(false);

      

Is there a way to make it work without this extra structure?

auto conds = fun<bool, 3>(false);

      

+3


source to share


1 answer


First, you can recursively construct a parameter pack using struct

for partial specialization (I show you this path because it belongs to # 2). This code is untested and doesn't care about the default value for elements, but it does give you an idea and the default value code can be easily added.

template<typename T, int N, typename... Rest>
struct fun_helper {
    typedef typename fun_helper<T, N - 1, T, Rest...>::type type;
};

template<typename T, typename... Rest>
struct fun_helper<T, 0, Rest...> {
    typedef std::tuple<Rest...> type;
};

template<typename T, int N>
typename fun_helper<T, N>::type fun() {
    return typename fun_helper<T, N>::type { };
}

      

In the second case, you can combine the above methods with a parameter package int

and use ...

to extend them, for example

Foo<Ints>...

      



which expands to

Foo<Int1>, Foo<Int2>, ...

      

in your function.

+1


source







All Articles