0

I am trying to hardcode a bunch of values in an array of objects, FloatParameterFields by calling the constructor of each object in the array. I am calling these constructors in another constructor, ParametersServerABS().

The array of objects FloatParameterFields is a private member of the ParametersServerABS class:

private:

    FloatParameterFields _floatParameters[FloatParameter::NUM_FLOAT_PARAMS];
    bool _safeMode;

In another file, I defined the enum and struct:

enum FloatParameter {
    CHIP_CLOCK_RATE_0 = 0,
    CHIP_CLOCK_RATE_1,
    CHIP_CLOCK_RATE_2,
    CHIP_CLOCK_RATE_3,
    CHIP_CLOCK_RATE_4,
    NUM_FLOAT_PARAMS
};

enum AccessModes {
    READ_ONLY = 0,
    SAFE_WRITE,
    WRITE,
    NUM_ACCESS_MODES
};

struct FloatParameterFields {

    public:

        FloatParameterFields() :
                upperBound(0),
                lowerBound(0),
                value(0),
                id(NUM_FLOAT_PARAMS),
                mode(NUM_ACCESS_MODES) {
        }

        FloatParameterFields(float upperBound, float lowerBound, float value, FloatParameter id,
                AccessModes mode) :
                upperBound(upperBound),
                lowerBound(lowerBound),
                value(value),
                id(id),
                mode(mode) {
        }

        float upperBound;
        float lowerBound;
        float value;
        FloatParameter id;
        AccessModes mode;

};

In my first attempt I did:

ParametersServerABS::ParametersServerABS() :
        _safeMode(true) {

    // Hardcoding the values to the struct
    _floatParameters[FloatParameter::CHIP_CLOCK_RATE_0](2.0, 2.0, 1.0,
            FloatParameter::CHIP_CLOCK_RATE_0, AccessModes::WRITE);
    _floatParameters[FloatParameter::CHIP_CLOCK_RATE_1](2.0, 2.0, 1.0,
            FloatParameter::CHIP_CLOCK_RATE_1, AccessModes::SAFE_WRITE);
    _floatParameters[FloatParameter::CHIP_CLOCK_RATE_2](2.0, 2.0, 1.0,
            FloatParameter::CHIP_CLOCK_RATE_2, AccessModes::WRITE);
    _floatParameters[FloatParameter::CHIP_CLOCK_RATE_3](2.0, 2.0, 1.0,
            FloatParameter::CHIP_CLOCK_RATE_3, AccessModes::WRITE);
    _floatParameters[FloatParameter::CHIP_CLOCK_RATE_4](2.0, 2.0, 1.0,
            FloatParameter::CHIP_CLOCK_RATE_4, AccessModes::READ_ONLY);

}

This gave the error:

no match for call to 'FloatParameterFields) (double, double, double, FloatParameter, AccessModes)'

Upon further research I tried:

    // Hardcoding the values to the struct
    _floatParameters[FloatParameter::NUM_FLOAT_PARAMS]= {FloatParameterFields(2.0, 2.0, 1.0,
                FloatParameter::CHIP_CLOCK_RATE_0, AccessModes::WRITE),
        FloatParameterFields(2.0, 2.0, 1.0,
                FloatParameter::CHIP_CLOCK_RATE_1, AccessModes::SAFE_WRITE),
        FloatParameterFields(2.0, 2.0, 1.0,
                FloatParameter::CHIP_CLOCK_RATE_2, AccessModes::WRITE),
        FloatParameterFields(2.0, 2.0, 1.0,
                FloatParameter::CHIP_CLOCK_RATE_3, AccessModes::WRITE),
        FloatParameterFields(2.0, 2.0, 1.0,
                FloatParameter::CHIP_CLOCK_RATE_4, AccessModes::READ_ONLY)}

And got the error:

no match for 'operator=' (operand types are 'FloatParameterFields' and '<brace-enclosed initializer list>')

I am most confused by my first attempt, why is it wrong? It seems to make sense yet I get an error... I even properly included the header files.

2 Answers 2

1

Before entering the opening { of your constructor, all of your members are already initialised. That includes the _floatParameters array and all of its elements. When you then do...

_floatParameters[FloatParameter::CHIP_CLOCK_RATE_0](2.0, 2.0, 1.0,
        FloatParameter::CHIP_CLOCK_RATE_0, AccessModes::WRITE);

...this is seen as attempting to call _floatParameters[FloatParameter::CHIP_CLOCK_RATE_0] as though it were a function-like object. It is not seen as an initialiser, since the objects have already been initialised.

Similarly, you later do:

_floatParameters[FloatParameter::NUM_FLOAT_PARAMS]= { ... };

which is attempting to use the initialisation syntax for an array after the array has already been initialised.

Instead, you could use the constructor's member initialisation list:

ParametersServerABS::ParametersServerABS()
  : _safeMode(true),
    _floatParameters{
      {2.0, 2.0, 1.0, FloatParameter::CHIP_CLOCK_RATE_0, AccessModes::WRITE},
      // and so on...
    }
{
}
Sign up to request clarification or add additional context in comments.

2 Comments

Oh, were they initialized in the part where I initialized a private array of structs?
@JustinLiang They are initialised when the object is constructed, immediately before entering the body of the constructor.
1

You're calling _floatParameters[FloatParameter::CHIP_CLOCK_RATE_0](...) as if you had an array of functions, and you're calling one of its items. Even though arrays of functions do exist in C++, it doesn't seem to be what you tried to achieve.

Simply, you cannot call constructor like that. Here's a correct example:

_floatParameters[FloatParameter::CHIP_CLOCK_RATE_0] = FloatParameterFields(2.0, 2.0, 1.0, FloatParameter::CHIP_CLOCK_RATE_0, AccessModes::WRITE);

Your another approach could have worked, but there's a bug.

_floatParameters[FloatParameter::NUM_FLOAT_PARAMS]= { ... }

You're assigning an initializer list (i.e. list of values) into the FloatParameter::NUM_FLOAT_PARAMS-th item of _floatParameters. To setup an array you'd assign to _floatParameters directly. That will work with vector, but won't work with plain old arrays.

_floatParameters = { ... }

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.