#How to put class instances in enum class (c++)

1 messages · Page 1 of 1 (latest)

pseudo knot
#

I would like to make use of an enum class to store several objects that are more complex than the native types as the following, but it requires a constant value

class A
{
  ...
  A(argT arg){...}
}
enum class
{
  a = A(foo),
  b = A(bar)
}

is there anyway to make the return value of a constructor constant?

#

for context, the code that I'm trying to write:

class Difusion_matrix
{
private:
    floatGrid3d           _matrix;
    unsigned short int    _dimX;
    unsigned short int    _dimY;
    unsigned short int    _dimZ;
    unsigned int          _sum;

public:
    Difusion_matrix(ratioGrid3d matrix)
    {
        _dimX = matrix.size();
        _dimY = matrix[0].size();
        _dimZ = matrix[0][0].size();

        /* compute sum */
        _sum = 0;
        for (auto x : matrix)
            for (auto y : x)
                for (auto z : y)
                    _sum += z;
        
        /* populate kernel with multipliers which summation equals 1 */
        _matrix = std::vector(_dimX, std::vector(_dimY, std::vector(_dimZ, 0.f)));
        for (auto x = 0; x < _dimX; x++)
            for (auto y = 0; y < _dimY; y++)
                for (auto z = 0; z < _dimZ; z++)
                    _matrix[x][y][z] = static_cast<float>(matrix[x][y][z]) / _sum;
    }

    std::array<int, 3> getDim() { return { _dimX, _dimY, _dimZ }; }
    floatGrid3d& operator ()() { return _matrix; }
};

enum class Kernels
{
    modified_floyd_steinberg_kernel = Difusion_matrix(
        {{{0, 0, 7},
          {3, 6, 2}},
         {{3, 6, 2},
          {1, 3, 1}}}),

    modified_Jervis_Judice_Ninke_kernel = Difusion_matrix(
        {{{0, 0, 0, 7, 5},
          {3, 5, 7, 5, 3},
          {1, 3, 5, 3, 1}},
         {{3, 5, 7, 5, 3},
          {2, 4, 4, 4, 2},
          {0, 1, 2, 1, 0}},
         {{1, 3, 5, 3, 1},
          {0, 1, 1, 1, 0},
          {0, 0, 1, 0, 0}}})
};
gleaming canyon
#

yeah, it might not be like Java, where you could do this

#

It might work with an int[][][]

#

and create the class at run_time or instantiate a private static const object outside and then putting a reference pointer or something

#

also Difusion_matrix use std::vector

#

which goes on the heap

pseudo knot
#

._. f

gleaming canyon
#

you could subclass and change the new operator, but it's gonna go on the heap right?

#

why not make those static creators ?

pseudo knot
#

wouldn't it means that the constructor only create one instance?

gleaming canyon
#

if you cache it yes

#

then it's a multiton (multiple singleton)

#

but in C++, it will probably leak, because when are you going to delete it?

#

or you use like a shared_ptr<T> ?

pseudo knot
#

it's fiiiiiine

#

there is like 12 matrix at most

gleaming canyon
#

well you could have an enum with all 12 types and <K,V> the int[][][]

#

and pass that (const enum&) to a creator method

#

that cache it via a static std::map<K,V>

pseudo knot
#

could just use a map

#

but that's for the gist of it

gleaming canyon
#

the point is that it's created on demand

#

unless you want to pre-allocate all of them at boot time

pseudo knot
gleaming canyon
#

in such case, I would create another method to pre-populate

#

why on the stack? 🤔

#

Difusion_matrix::initializeAll()

pseudo knot
#

anywhere; just that it's ideal if it doesn't have to populate anything at run-time

gleaming canyon
#

also Difusion_matrix should be 2 f

Diffusion_matrix

#

it will populate stuff at run-time, because std::vector<T>

pseudo knot
gleaming canyon
#

otherwise you need to create a template that is acting on raw int[][][]

#

without doing any allocation

#

and without virtual either

pseudo knot
#

I rather not; there is a normalisation step that I rather not do by hand:

gleaming canyon
#

we used that trick at my ex-workplace

#

well normalization is done at run-time then

#

otherwise you need to pre-generate the code normalized

#

or to normalized it with constexpr at compile-time

pseudo knot
#

that would be the point if only we could have an inline or constexpr constructor

gleaming canyon
#

but your point is what exactly?

#

speed? space? fun? practice?

pseudo knot
#

speed, and to see if I could use enum

#

mostly to use enum

#

since it makes sense, I mean, on papper

gleaming canyon
#

check if you can use int[][][] inside the enum

#

first

#

but normalization would be run-time overhead either once or each call

pseudo knot
#

I tried puting value={{1, 2},{3 4}} kind of stuff; doesn't work even tho that should be constant

gleaming canyon
#

or read-write

#

I dunno, I remember doing weird stuff with C++ enum

#

but that was a long-time ago

pseudo knot
#

well whatever then I guess I'll give up; meanwhile to keep prototyping I have been using a simple class