1

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?

3
  • 1
    use std::vector instead. Commented Aug 24, 2012 at 10:32
  • 2
    please stop shouting. reserve all UPPERCASE identifiers for macros. Commented Aug 24, 2012 at 10:37
  • I see, so any form of constant should not be uppercase? Commented Aug 24, 2012 at 11:02

3 Answers 3

1

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

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

2 Comments

An example of the compile time version would be welcome. Thank you.
Maybe the comment below is an example of that? Apologies, I read through one answer at a time and haven't looked ahead.
1
#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;
}

2 Comments

Is this a compile time example? It looks remarkably similar to the link that @AndrewTomazos posted.
@user1423893: no, it's run-time. doing this at compile time is a bit more intricate. for doing it with templates you need variadic template support (and visual c++ doesn't have that yet as of version 11), but it can be done portably by using e.g. the Boost preprocessor library.
1

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);

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.