A const big array needs to be initialized

I have a static array of doubles inside my class, and I would like it to be const, but I need to initialize it somehow. What is the best way of ensuring that it will be "const" after the constructor returns?

class DFTDriver {        
public:
    static const size_t tblsize = 16384;
    DFTDriver() {
        for (unsigned i = 0; i != tblsize; ++i) {
            sintbl[i] = std::sin(i * TAU / tblsize);
            costbl[i] = std::cos(i * TAU / tblsize);
        }
    }
private:
    static double sintbl[tblsize];
    static double costbl[tblsize];
};

I know I need a computation to initialize them, so it wouldn't be reasonable to ask them to be const; however, the array is clearly "semantically const".

I see that here there is an answer if I am initializing a vector instead of an array. Is it possible to use a similar approach?

I would like to be able to do it without appealing to new C++11 constructs, but if it's not possible, then let C++11 do it.

Answers


I know that a lot of people here would love to vote down my answer, nevertheless I hope they will think a bit before doing so.

Maybe this problem is exactly the case when simple casting should be used. The data field should be declared const. This will guarantee that it will not be accidentally changed somewhere. You should allocate non const pointer in your initialization function and point it to your data. Do casting, add detailed comment with explanation why you are doing this and you will be fine. Pros:

  1. The code will be absolutely clear;
  2. It will run without trouble on any platform/compiler;
  3. Casting will be just in one place that is not likely to be changed.

p.s. I would recommend adding static instance of your class and making your ctor private. This will guarantee that the ctor will be called in the very beginning:

class DFTDriver
{        
private:

    DFTDriver() { .... }

    static DTFDriver inst;

    static double sintbl[tblsize];
    static double costbl[tblsize];
};

The other answer with generated source also makes sense although the code will be more difficult to maintain.


Make a program to generate the tables

FILE * file = fopen( "sintbl.cpp", "w" );
fprintf( file, "const double DFTDriver::sintbl[] = {\n" );
for (unsigned i = 0; i != tblsize; ++i) {
    fprint( file, "  %f , \n", std::sin(i * TAU / tblsize) );
}
fprintf( file, "};\n" );
fclose( file );

And then compile the generated file and link it into your program.


This should work

class DFTDriver {   
    template<class ElementType, size_t size>
    struct Buffer
    {
        Buffer(ElementType(*initializer)(size_t i)) {
            for(size_t i = 0; i < size; ++i) {
                data[i] = initializer(i);
            }
        }
        const ElementType operator[](size_t i) const {return data[i];}
        ElementType& operator[](size_t i) {return data[i];}
        ElementType data[size];
    };
    double initSinbl(size_t i) { 
         return std::sin(i * TAU / tblsize);
    }
    double initCosbl(size_t i) {
        return std::cos(i * TAU / tblsize);
    }
public:
    static const size_t tblsize = 16384;
private:
    //initSinbl and initCosbl can be replaced with lambdas in c++11
    static const Buffer<double, tblsize> sintbl(&initSinbl);
    static const Buffer<double, tblsize> costbl(&initCosbl);
};

Need Your Help

Comparing dicts and update a list of result

python compare dictionary

I have a list of dicts and I want to compare each dict in that list with a dict in a resulting list, add it to the result list if it's not there, and if it's there, update a counter associated with...