Thex Thex - 17 days ago 5
C++ Question

Square brackets overloading => no operator matches operands

I'm currently having a bit of trouble overloading the square brackets in a custom vector class.

My class basically looks like this:

typedef uint32_t u32; // This is not actually here, but so you get the idea. Also, it is included in the problematic call's file

template<class T>
class JFFVector
{
public:
//Init and stuff
T& operator[](u32 iIndex)
{
return m_pData[iIndex + miDataOffset];
}

private:
T* m_pData;
u32 m_iDataOffset;
}


And within this classes functions, I can call (*this)[0] and everything works.
Now the issue I'm having is with a class that has a member as follows:

class TOtherClass
{
public:
// Stuff
void DoSomething() const
{
for (u32 i; i < m_tItems.size(); ++i)
m_tItems[i]->DoStuff(); // Which is a const function
}

private:
JFFVector<const JFFItem*> m_tItems;
}


The issue being that my compiler throws an error at my face saying


no operator "[]" matches these operands

operand types are: const JFFVector[u32]

typedef uint32_t u32.


So one thing I noticed is that if I make m_tItems a pointer, then I can do "(*m_tItems)[i]->DoStuff()" and it works fine. But I do not understand why this works while it doesn't with a non-pointer version.
(Also, I tried with a simple int instead of u32, and, with no surprise, it didn't work)

Does anyone have any idea what I did wrong please? And, if not trivial, why is it wrong?

(Sorry if this has been answered already, I tried searching for a similar issue but found nothing that looks like this issue)

Answer

There's two indexing operators you can overload -- one which works on a const JFFVector and returns a T const&, and one which works on a JFFVector and returns a T&. You've only implemented the second.

You can implement it similarly to the non-const version like so:

T const& operator[](u32 iIndex) const   // <-- note the two `const`s
{
    return m_pData[iIndex + miDataOffset];
}

Note that this overloading is not specific to operator[], but rather all methods (which can be overloaded by const or non-const).

The reason you need the const version in your code is that DoSomething() is declared const, thus this is const TOtherClass* within that method, and by extension all its members, notably m_tItems here, are const within the method, and so only const methods can be called on them. Since there is no const version of operator[] defined for m_tItems, the compiler gives you that error.