3

I have the following class:

const unsigned E = 256;

class A {
    public:
        static const unsigned x[E];
    ...
}

and I want to initialize x as follows:

const unsigned A::x[E] = { 1, 2, 3, ..., E };

The above assignment seems to be trivial for now. But, the point is to initialize the value of array x based on the index. A quick try seems to tell me that even with c++11 this isn't possible.

Any input?

Thanks.

4
  • It wouldn't technically be initialization, but std::iota may suit your needs... Commented Apr 19, 2014 at 19:04
  • What's the point of the array anyway? Commented Apr 19, 2014 at 19:16
  • It sounds like std::integer_sequence, but it will not be available until C++14. en.cppreference.com/w/cpp/utility/integer_sequence Commented Apr 19, 2014 at 19:16
  • The sequential initialization is a first use case. It may gets complicated later such as: { f(0), f(1), f(2), ... }. Commented Apr 19, 2014 at 19:22

2 Answers 2

2

If you don't mind storing a std::array instead of a C array, this is pretty simple with an integer sequence:

template <int...I>
struct indices {};
template <int N, int...I>
struct make_indices : make_indices<N-1, N-1, I...> {};
template <int...I>
struct make_indices<0, I...> : indices<I...> {};

template <typename T, int...I>
constexpr std::array<T, sizeof...(I)>
iota_array_helper(indices<I...>) {
  return {I...};
}

template <typename T, std::size_t N>
constexpr std::array<T, N>
iota_array() {
  return iota_array_helper<T>(make_indices<N>());
}

which you can use as:

const unsigned E = 256;

class A {
    public:
        static const std::array<unsigned, E> x;
    ...
};

std::array<unsigned, E> A::x = iota_array<unsigned, E>();

Here it is live.

Sign up to request clarification or add additional context in comments.

2 Comments

This works but still needs a bit of modification because I want the array to be A::x[0]=1, [1]=2, etc. These level of template is beyond me. What is a good reference to read up on it?
@WenSiangLin : FYI, the only modification needed to offset the integers so that A::x[0]=1, [1]=2 holds true is to change return {I...}; to return {(I+1)...};. This can be generalized by adding an additional non-type template parameter to iota_array and iota_array_helper to hold the offset.
0

You can with some recursion trick

template<int... values>
struct myclass {
    static const unsigned char x[sizeof...(values)];
};

template<int... values>
const unsigned char myclass<values...>::x[sizeof...(values)] = { values... };

template<int count, int... values>
struct iota_array {
    typedef typename iota_array<count-1, count-1, values...>::value value;
};

template<int... values>
struct iota_array<0, values...> {
    typedef myclass<values...> value;
};

typename iota_array<E>::value myinstance;

The fact that you CAN of course doesn't mean that you should.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.