72

I have the following class:

class risc { // singleton
    protected:
        static unsigned long registers[8];

    public:
        unsigned long operator [](int i)
        {
            return registers[i];
        }
};

as you can see I've implemented the square brackets operator for "getting".
Now I would like to implement it for setting, i.e.: risc[1] = 2.

How can it be done?

jww
  • 97,681
  • 90
  • 411
  • 885
SagiLow
  • 5,721
  • 9
  • 60
  • 115

2 Answers2

98

Try this:

class risc { // singleton
protected:
    static unsigned long registers[8];

public:
    unsigned long operator [](int i) const    {return registers[i];}
    unsigned long & operator [](int i) {return registers[i];}
};
Andrew Durward
  • 3,771
  • 1
  • 19
  • 30
  • 16
    You can also return a `const long&`. If it weren't a native type then that way would be preferred but for types like `long` it's fine to return it by value. – Seth Carnegie Jun 16 '12 at 20:00
  • Note that it would be a good idea to add a test on i to make sure it's a number between 0 and 7 inclusive. And when dealing with much more complex types than a long, you generally create a reference class (riscDataRef) which holds the necessary information to let you make changes to the main class. – Alexis Wilke Jun 16 '12 at 21:15
  • 2
    Shouldn't the ints be replaced with size_t? – Trevor Hickey Aug 03 '15 at 20:22
  • @Andrew unsigned long operator [](int i) const {return registers[i];} Will the above be called ? I see the other one being called for both getting and setting unsigned long & operator [](int i) {return registers[i];} – tanweer alam Aug 17 '16 at 01:07
  • @tanweeralam The const variant will be called when the object or reference on which it's called is const. E.g. `const risc r; r[0];` – Andrew Durward Aug 17 '16 at 17:54
  • @AndrewDurward I used your code and called like this risc m; m[0]=1; DEBUG_PRINT("%d",m[0]);//{I expect the const one to be called here}. Even though the answer is correct printed, in both cases only the second function is called. unsigned long & operator [](int i) {return registers[i];} – tanweer alam Jan 18 '17 at 09:50
  • @tanweeralam I've already addressed this. See my previous comment. If that doesn't help then please post a new question rather than using the comments section. – Andrew Durward Jan 18 '17 at 13:47
  • @AlexisWilke, STL containers have the `at` function for this purpose which checks the boundaries. – LRDPRDX Feb 13 '22 at 19:07
18

You need to return a reference from your operator[] so that the user of the class use it for setting the value. So the function signature would be unsigned long& operator [](int i).

Naveen
  • 74,600
  • 47
  • 176
  • 233