7

I have the following template class:

template <unsigned N>
class XArray {
  static const int Xdata[N];
};

I want to initialize the static const array for each XArray<N> I used, for example, let XArray<N>::Xdata = {1, 2, 3, ..., N}. How to make it?

Oliver Q
  • 123
  • 1
  • 4

3 Answers3

4

you declared a static const int array in your class,so you must define the static member out of the class declaration,just like this:

template<unsigned N>
class XArray
{
public:
static const int array[N];
};
template<unsigned N>
const int XArray<N>::array[N] = {1,2,3,4,5};

But something you must pay attention to is that: when you use this template you must make sure that the "N" bigger than the number of your initialized array;

minicaptain
  • 1,196
  • 9
  • 16
  • But can we use a constexpr function to init the static array with the full sequence of number from 1 to N..,? – alexbuisson Jul 13 '13 at 08:05
  • I don't think so.Because when you declare a const member you must give it an initialized value,if you want to initialize every element of a const static array,you must use const_cast to change the const element to normal. – minicaptain Jul 13 '13 at 14:39
2

EDIT:

It seems someone have already provided the solution for your problem in other question, and the answer is quite the same as mine.

Also, for more generic answer, you can check out answers to this question.


Code

If you don't mind using C++11 features, then variadic templates may come handy:

template <unsigned ...Args>
struct XArrayData
{
    static const int Values[sizeof...(Args)];
};

template<unsigned N, unsigned ...Args>
struct _XArrayGenerator
{
    typedef typename _XArrayGenerator<N - 1, N, Args...>::Xdata Xdata;
};

template<unsigned ...Args>
struct _XArrayGenerator<1, Args...>
{
    typedef typename XArrayData<1, Args...> Xdata;
};

template<unsigned N>
struct XArray
{
    typedef typename _XArrayGenerator<N>::Xdata Xdata;
};

template <unsigned ...Args>
const int XArrayData<Args...>::Values[sizeof...(Args)] = { Args... };

Explanation

XArray template struct takes the number of array elements as a template parameter (N). In the compilation time, it uses _XArrayGenerator to generate template paremeter list with N consecutive numbers. It begins with the number N, and then recursively uses itself until it reaches 1. At this point, the template parameter list looks like this:

1, 2, ..., N

The last thing to do is to pass these parameters to XArrayData. The last line of the code (definition of the actual array) uses the parameters to initialize the array.

Usage

for (int i = 0; i < 3; ++i)
    cout << XArray<3>::Xdata::Values[i] << endl;

Output:

1
2
3
Community
  • 1
  • 1
podkova
  • 1,019
  • 7
  • 16
0

You can initialize as shown below. See inline comments for my explanation.

template <unsigned N>
class XArray {
    private:
        static const int Xdata[N];
    public:
        //I added this for illustration purpose
        void print()
        {
            for (int i = 0; i < N; ++i)
            {
                std::cout << Xdata[i] << std::endl;
            }
        }
};

//you can initialize like this
//automatic size counting works with static arrays
//here I initialize with 3 elements
//make sure you don't use N < 3 anywhere
template <unsigned N>
const int XArray<N>::Xdata[] = {1,2,3};

int main(void)
{
    XArray<3> obj1; //N = 3: This is okay.
    XArray<8> obj2; //N > 3: This is okay. Remaining elements will be 0.
    XArray<2> obj3; //N < 3: This is also okay.
    obj1.print();
    obj2.print();
    obj3.print(); //but this will give compilation error

    return 0;
}
bibbsey
  • 969
  • 2
  • 9
  • 14