18

i need a way to initialize const elements of an array for the program i am currently working on. The problem is that i have to initialize these elements with a function, there is no way to do it like this:

const int array[255] = {1, 1278632, 188, ...};

because its alot of data i have to generate. What i tried is to memcpy data to the const int's but that can't work and hasn't worked.

 const int array[255];

 void generateData(){
      for(int i = 0; i < 255; i++) {
          initializeSomehowTo(5, array[i]);
      }
 }

I hope you understand what i am trying, sorry if i doubled the question, i must have overlooked it.

1
  • 6
    You can't do const int array[255] = initializeMyArray(), but if you used std::array, you could do const std::array<int, 255> = initializeMyArray() Commented Jun 5, 2017 at 22:43

3 Answers 3

20

How about this?

#include <array>
typedef std::array<int, 255> Array;

const Array array = generateData();

Array generateData(){
    Array a;
    for(int i = 0; i < a.size(); i++) {
        initializeSomehowTo(a[i]);
    }
    return a;
}
Sign up to request clarification or add additional context in comments.

1 Comment

this works great, only thing is that const int array[10][10][10]; looks really scary: const std::array<std::array<std::array<int, 10>, 10>, 10> Array; ;-)
6

The easiest approach is to get the filled array from a function and use that to initialize your const (or constexpr) object. However, built-in arrays can't be copied but std::array<T, N> be:

std::array<T, 255> array = initializeData();

If you need a built-in array, I can imagine initializing a static member of a class (template, actually) where the index is expanded from indices expanded from an std::make_index_sequence<255> and used as positional argument in the array, i.e., something along these lines:

#include <algorithm>
#include <iostream>
#include <iterator>
#include <utility>

int some_function(std::size_t i) { return i; }

template <typename> struct initialized_array_base;
template <std::size_t... I>
struct initialized_array_base<std::index_sequence<I...>> {
    static const int array[sizeof...(I)];
};

template <std::size_t... I>
int const initialized_array_base<std::index_sequence<I...>>::array[sizeof...(I)]
    = { some_function(I)... };

struct initialized_array
    :initialized_array_base<std::make_index_sequence<256>> {
};

int main() {
    std::copy(std::begin(initialized_array::array),
              std::end(initialized_array::array),
              std::ostream_iterator<int>(std::cout, " "));
    std::cout << '\n';
}

1 Comment

Wow that looks scary for such a simple task ;-)
3

You can create a writable array, initialize it, and, then, create a const reference to it.

int arry[255];

void generateData(){
  for(int i = 0; i < 255; i++) {
      initializeSomehowTo(5, arry[i]);
  }
}

const int (&array)[255] = arry;

3 Comments

This does not stop arry from getting modified, right?
I think you can also std::static_cast to a const reference
An extra level of indirection (for the reference variable that also has static storage) may not optimize away. I would definitely recommend not using this, since returning a std::array<> from an initializer function avoids any performance downside.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.