user1423893
user1423893

Reputation: 796

Generating static array values from function in a header

In C# I can generate a static array using a function:

private static readonly ushort[] circleIndices = GenerateCircleIndices();

....

    private static ushort[] GenerateCircleIndices()
    {
        ushort[] indices = new ushort[MAXRINGSEGMENTS * 2];
        int j = 0;

        for (ushort i = 0; i < MAXRINGSEGMENTS; ++i)
        {
            indices[j++] = i;
            indices[j++] = (ushort)(i + 1);
        }

        return indices;
    }

Using C++ I believe the following is the correct way to generate a static array:

.h

static const int BOXINDICES[24];

.cpp (constructor)

static const int BOXINDICES[24] =
{ 
    0, 1, 1, 2, 
    2, 3, 3, 0, 
    4, 5, 5, 6, 
    6, 7, 7, 4, 
    0, 4, 1, 5, 
    2, 6, 3, 7 
};

How can I do the same for the circleIndices but use a function to generate the values?

.h

static const int CIRCLEINDICES[];

.cpp (constructor)

static const int CIRCLEINDICES[] = GenerateCircleIndices();  // This will not work

Do I have to initialise the array elements with values of 0 then call the function?

Upvotes: 1

Views: 151

Answers (3)

Andrew Tomazos
Andrew Tomazos

Reputation: 68648

It depends if you want the function evaluated at runtime or compile time. In C# it is going to happen at runtime, but C++ gives you the option of doing it at compile time.

If you want to do it at runtime you can use a static initialized class:

struct S
{
    int X[N];

    S() { for (int i = 0; i < N; i++) X[i] = ...; }
};

S g_s;

Here the constructor is called before the entry to main to setup your array.

If you want to do it at compile time than you can use either templates or macros in various ways not possible in C#. If you do it at compiletime the data of the array will be calculated by the compiler and filled out with a memcpy by the loader from the static area of your application image directly into your process address space. Here is an example:

#include <iostream>
#include <array>
using namespace std;

constexpr int N = 10;
constexpr int f(int x) { return x % 2 ? (x/2)+1 : (x/2); }

typedef array<int, N> A;

template<int... i> constexpr A fs() { return A{{ f(i)... }}; }

template<int...> struct S;

template<int... i> struct S<0,i...>
{ static constexpr A gs() { return fs<0,i...>(); } };

template<int i, int... j> struct S<i,j...>
{ static constexpr A gs() { return S<i-1,i,j...>::gs(); } };

constexpr auto X = S<N-1>::gs();

int main()
{
        cout << X[3] << endl;
}

See: C++11: Compile Time Calculation of Array

Upvotes: 1

doron
doron

Reputation: 28892

In C++, a function cannot return an array and therefore cannot be used to initialize an array. The two options that you have are to either to use:

static const int* CIRCLEINDICES = GenerateCircleIndices();

Or

static int CIRCLEINDICES[some_size];
GenerateCircleIndices(CIRCLEINDICES);

Upvotes: 1

Cheers and hth. - Alf
Cheers and hth. - Alf

Reputation: 145279

#include <array>        // std::array
#include <utility>      // std::begin, std::end
#include <stddef.h>     // ptrdiff_t
using namespace std;

typedef ptrdiff_t Size;

template< class Collection >
Size countOf( Collection const& c )
{
    return end( c ) - begin( c );
}

typedef array<int, 24> CircleIndices;

CircleIndices generateCircleIndices()
{
    CircleIndices   result;
    for( int i = 0;  i < countOf( result );  ++i )
    {
        result[i] = i;
    }
    return result;
}

CircleIndices const circleIndices = generateCircleIndices();

#include <iostream>
int main()
{
    for( int i = 0;  i < countOf( circleIndices );  ++i )
    {
        wcout << circleIndices[i] << ' ';
    }
    wcout << endl;
}

Upvotes: 1

Related Questions