Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is it possible to construct the elements of a member array depending on an integral template parameter?

Assume:

template<class T,int N>
struct A {
  A(): /* here */ {}

  T F[N];
};

I need the elements of F[] to be constructed with {0,1,2,...,N-1}. If possible I would like to avoid recursively defined template structs with defining the last level as template<class T> struct A<T,0> and doing some complicated template tricks. Can C++11 initializer lists help?

This is similar Template array initialization with a list of values, but it does not construct the elements with the increasing value. It sets it later in a run-time loop.

like image 442
ritter Avatar asked Oct 11 '12 09:10

ritter


People also ask

Can member functions be declared as template?

The term member template refers to both member function templates and nested class templates. Member function templates are function templates that are members of a class or class template. Member functions can be function templates in several contexts.

Can a non-template class have a template member function?

A non-template class can have template member functions, if required. Notice the syntax. Unlike a member function for a template class, a template member function is just like a free template function but scoped to its containing class.

What can the template parameter in C++ template definition be?

A template parameter is a special kind of parameter that can be used to pass a type as argument: just like regular function parameters can be used to pass values to a function, template parameters allow to pass also types to a function.

Is it true for template type parameter it will take long time to execute?

Explanation : Because of template type parameters, It will work with many types and saves a lot of time.


2 Answers

You can do this with a variadic value template and constructor delegation:

template<int... I> struct index {
    template<int n> using append = index<I..., n>; };
template<int N> struct make_index { typedef typename
    make_index<N - 1>::type::template append<N - 1> type; };
template<> struct make_index<0> { typedef index<> type; };
template<int N> using indexer = typename make_index<N>::type;

template<class T, int N>
struct A {
  template<T...I> A(index<I...>): F{I...} {}

  A(): A(indexer<N>{}) {}

  T F[N];
};

This uses the sequence pack generator from Calling a function for each variadic template argument and an array

like image 192
ecatmur Avatar answered Oct 06 '22 00:10

ecatmur


Assuming some kind of indices solution is available:

A(): A(make_indices<N>()) {}

// really a private constructor
template<int... Indices>
explicit A(indices<Indices...>)
    // Can be an arbitrary expression or computation, too, like
    // (Indices + 3)...
    : F {{ Indices... }}
{}

If your compiler doesn't support delegating constructors, one option is to switch to std::array<T, N> and use a private static helper that returns an initialized array, such that the default constructor would become:

A(): F(helper(make_indices<N>())) {}

This would of course incur an additional (move) construction.

like image 39
Luc Danton Avatar answered Oct 05 '22 22:10

Luc Danton