0

I have a class with a const static C-array in it

// Header file
class test
{
    const static char array[];
};

I am trying to initialize it somewhere in the code but not in the straight-forward way like

// Source file
const char test::array[] = {'1','2','3'};

because the values are calculated using some other constant values so i need to use a function to do that. something like

CONST_VALUE = 4;
void func(int a[3]){
    a[0]=2*CONST_VALUE;
    a[1]=10*CONST_VALUE;
  ...
}

The point is that i don't know where to define and use such a function, should it be a member function? a global function? and when should i call it so it happens only once?

shl mig
  • 19
  • 1
  • 2
    It's very easy if you have a [`std::array`](https://en.cppreference.com/w/cpp/container/array) instead, as then you could call a function which *returns* the array so it can be used in the initialization (i.e. `const std::array test::array = function_for_initialization();`) – Some programmer dude Aug 12 '19 at 08:37
  • Is it your intent to have the array size deduced from the initializer? – StoryTeller - Unslander Monica Aug 12 '19 at 08:41
  • @StoryTeller no, the size in known – shl mig Aug 12 '19 at 08:43
  • @Someprogrammerdude, i know but i have a C-array – shl mig Aug 12 '19 at 08:44
  • But you probably don't need a C-style plain array. Everything you can do with a plain C-style array you can do with `std::array` (well, with the exception of the array decay-to-pointer thing, which can be emulated really easy). – Some programmer dude Aug 12 '19 at 08:47
  • And if the size isn't known use `std::vector`. Unless the size is known first after `main` have been called. Then you have to do the initialization after you learn the size, and then you can't make the array or vector constant. – Some programmer dude Aug 12 '19 at 08:54
  • 1
    @shlmig maybe you can elaborate why a c-style array is required here ? as you may access the array of the vector with the data() function. – darune Aug 12 '19 at 09:13
  • Oh and you should probably elaborate on your *actual* problem. Why do you need a C-style array? Why does it have to be `const`? Knowing what problem you're really trying to solve could help us to help you with that problem instead. – Some programmer dude Aug 12 '19 at 11:59

4 Answers4

0

Using a c-style array

Just initialize it straight away:

// Header file
class test
{
    static inline const char array[]{2 * CONST_VALUE, 10 * CONST_VALUE};
};

Using a std::array

// Header file
class test
{
    static inline const std::array<2, char>{2 * CONST_VALUE, 10 * CONST_VALUE};
};

Using a std::vector

A vector is just a simpler solution than using an array:

// Header file
class test
{
    static inline const std::vector<char> array{2 * CONST_VALUE, 10 * CONST_VALUE};
};
darune
  • 10,480
  • 2
  • 24
  • 62
0

If you want to use dynamic allocation it might look like that:

class test
{
    const static char* array;
};
char* foo(int arr_size) {
    char* arr = new char[arr_size]();
    // other logic
    return arr;
}
const char* test::array = foo(10);

There is no practical need to delete this memory, unless you want to use your module as a shared library loaded and unloaded in runtime.

For the fixed size array I think you should use std::array:

#define ARR_SIZE 4
class test2
{
    const static std::array<char, ARR_SIZE> array;
};
std::array<char, ARR_SIZE> foo2() {
    std::array<char, ARR_SIZE> arr;
    arr[0] = 'x';
    // other logic
    return arr;
}
const std::array<char, ARR_SIZE> test2::array = foo2();

Finally if you must deal with C-style array, you can try the hack with function calculating each element separately:

class test3
{
    const static char array[ARR_SIZE];
};

char calculateElement(int index) {
    if (index == 0) {
        return 'x';
    } else if (index == 1) {
        return 'y';
    }
    // rest of the logic
    return 0;
}
const char test3::array[ARR_SIZE] = {
    calculateElement(0),
    calculateElement(1),
    calculateElement(2),
    calculateElement(3) };
pptaszni
  • 5,591
  • 5
  • 27
  • 43
0

If all func() does is assignment, then you can convert these assignments to initializer values:

const char test::array[] {
    2 * CONST_VALUE,
    10 * CONST_VALUE
};

But if func() has other logic in it, then you can use an std::array instead:

std::array<char, 3> func()
{
    std::array<char, 3> ar{};
    ar[0]=2*CONST_VALUE;
    ar[1]=10*CONST_VALUE;
    // ...

    return ar;
}

class test {
    static const std::array<char, 3> array;
};

const std::array<char, 3> test::array = func();
Nikos C.
  • 50,738
  • 9
  • 71
  • 96
0

If you use std::array instead of C-style array you can use a constexpr lambda to initialize it. See Compiler Explorer https://godbolt.org/z/izhWcR

class test
{
    constexpr static std::array<char, 2> mArray1 = [](){ 
        char v = const_a + const_c;
        return std::array<char, 2>{ const_a, v }; 
    }();
};
Generic Name
  • 1,083
  • 1
  • 12
  • 19