How to calculate initialization of const array (make const look-up-tables)?

Background: I am attached to arm-arago-linux-gnueabi-g++ (GCC) 4.3.3 . Although answers requiring C ++ 11 or later are also welcome, please expressly express any language requirement later than C ++ 03.

The object constructor fills in the values ​​in the tables that will be used by the algorithm.

Since this table does not change and should not change, I want them to be const, how to do this?

Complexity # 1, values ​​are generated using calculations, and I don’t want to hardcode them in the source file.

Complexity No. 2, the calculation sometimes depends on the inputs, which are available only at runtime.

Difficulty No. 3, I don’t know why, but I don’t want the array to be static, although the values ​​can be the same for all objects (cases when the values ​​are independent of the runtime input).

Complexity # 4 is an array, so the list of initializers in C ++ 03 will not work.

Edit1: A few weeks after this post, I found that std :: array and std :: vector are a very good alternative to the C-style array when std :: array is not available.

+5
source share
2 answers

You can encapsulate tables in a personal type with one instance of a const this type in your object, and then redirect the corresponding constructor parameters to a private object; this works because even a const object does not have a const value during its construction.

For instance:

 class MyClass { const struct Tables { double x[1000]; double y[200]; Tables(int i, double d) { x[i] = d; y[200 - i] = -d; } } tables; public: MyClass(int i, double d) : tables(i, d) {} }; MyClass c(20, 5.5); 

Another method is to build tables in an ephemeral mutable array, whose lifetime is limited by the constructor's lifetime, and then initialize the const array from these mutable arrays.

Using C ++ 11 std::array (since std::array types cannot be initialized):

 class MyClass { static std::array<double, 1000> buildArray(...) { std::array<double, 1000> array; ... // fill array return array; } const std::array<double, 1000> mArray; public: MyClass(...) : mArray(buildArray(...)) {} }; 

Note that std::array easy to express in C ++ 03; it does not depend on any features of the C ++ 11 language.

If you are worried about the overhead of returning a large array, do it, even C ++ 03 compilers are able to optimize large arrays.

+3
source

I think you could implement a class containing the actual non const array. This way you can easily calculate the values ​​in the constructor.

Then this class would need to implement operator[] , which can be used as an array. Or it can also just return a const reference to an array.

Implementation Example:

 #include <iostream> using namespace std; class const_array { int *arr; size_t size; public: const_array(size_t size, int typ): size(size) { arr = new int[size]; size_t i; int val = 0; for (i=0; i<size; i++) { val += typ; arr[i] = val; } } const_array(const const_array & src): size(src.size) { arr = new int[size]; size_t i; for (i=0; i<size; i++) { arr[i] = src.arr[i]; } } ~const_array() { delete[] arr; } const int * const getArray() const { return arr; } int getSize() const { return size; } const int& operator[](int i) { return arr[i]; } }; int main() { const_array a(16, 4); // int *arr = a.getArray(); error const int *arr = a.getArray(); int j = a[2]; int k = arr[2]; // int * pj = &(a[2]); error const int * pj = &(a[2]); const int * pk = &(arr[2]); cout << "a[2]=" << j << " (" << pj << ") - a.getArray[2]=" << j << " (" << pj << ")" << endl; return 0; } 
+1
source

Source: https://habr.com/ru/post/1211253/


All Articles