[Work-Around?] Overload Two Operators in the Same Class Instance Function

Hi.

I’m wondering if it’s possible to define a class instance function that overrides the ‘[]’ and ‘=’ operators at the same time.

The use case I’m thinking of is shown in the setup() function below. But, obviously, the syntax in the class definition is wrong. If this is possible, I’d appreciate someone cluing me in to the proper syntax.

Thanks.

class myClass {
  public:
  myClass& operator[] (const uint8_t i) operator= (const uint32_t v)  {
    // do something special with index 'i' and value 'v'
    return *this;
  }
};

myClass myObject;

void setup() {
  uint32_t someValue = 5;
  uint8_t index = 7;
  
  myObject[index] = someValue;
}

void loop() {}

Well, this behaves as I want. But, is it a kludge?

class myClass {
  private:
    uint8_t savedIndex;

  public:
    myClass& operator[] (const uint8_t i) {
      savedIndex = i;
      return *this;
    }

    myClass& operator= (const uint32_t v)  {
      Serial.print("Doing Something Special with Value = ");
      Serial.print(v);
      Serial.print(", at Index = ");
      Serial.println(savedIndex);
      return *this;
    }
};

myClass myObject;

void setup() {
  Serial.begin(115200);
  delay(1000);
  
  uint32_t someValue = 5;
  uint8_t index = 7;

  myObject[index] = someValue;
}

void loop() {}

Think about what happens in this pseudo-code using your class:

value1 = myClass[1];
value2 = myClass[2];
value3 = myClass[3];

value1 = someValue;

The indexes are dependent, value1 would be index 3 rather than 1 and that could lead to problems.

A safer way would be using an inner class:

class myClass {
  private:

    class mySubClass {
      private:
        myClass* owner;
        uint8_t index;
      public:
        mySubClass(myClass* owner, uint8_t index)
          : owner(owner), index(index)
        {}

        mySubClass& operator=(uint32_t value)  {
          owner->doSomething(index, value);
          return *this;
        }
    };

    void doSomething(uint8_t index, uint32_t value) {
      Serial.print("Doing Something Special with Value = ");
      Serial.print(value);
      Serial.print(", at Index = ");
      Serial.println(index);
    }

  public:
    mySubClass operator[] (uint8_t index) {
      return mySubClass(this, index);
    }
};

myClass myObject;

void setup() {
  Serial.begin(115200);
  delay(1000);

  uint32_t someValue = 5;
  uint8_t index = 7;

  myObject[index] = someValue;
}

void loop() {}

This way, the indexes would be independent of each other.

Interesting. Thanks.

Haven't worked with sub-classes yet.

So, is 'mySubClass' both the name of the class (i.e. a type) AND the name of the private instance of that class within myClass (i.e. a private data member)?

gfvalvo:
Haven't worked with sub-classes yet.

So, is 'mySubClass' both the name of the class (i.e. a type) AND the name of the private instance of that class within myClass (i.e. a private data member)?

Never mind. On further study of your example, I'm now thinking that:

    mySubClass operator[] (uint8_t index) {
      return mySubClass(this, index);
    }

is returning an anonymous instance of mySubClass whose 'operator=' operator then invokes the doSomething() method of the enclosing class / object.

After a little more Googling, I'm thinking the term Nested Class is better than Sub-Class as the latter seems to imply a Derived class.