1

I want to add a overload the operator [] in my class. Operator overloading is not something I've had to do before.

I want to write an implementation to do the following:

    myclass a;
    a["test"] = 123;
    int test = a["test"];      

So far in my class the prototype looks like this:

    string operator[](const char* cpszLabel);

The implementation isn't complete and looks like this:

    string myclass::operator[](const char* cpszLabel) {
        string strContent;
        if ( cpszLabel != nullptr ) {
        }
        return strContent;
    }

What I'm not sure about is how to reference the data that is being assigned or does this require overloading the '=' too?

I've added an overload for the '=' operator, but this doesn't get called:

Prototype:

    string operator=(int intData);

Implementation:

    string myclass::operator=(int intData) {
        char szString[24];
        sprintf(szString, "\"%d\"", intData);
        return string(szString);
    }
SPlatten
  • 5,334
  • 11
  • 57
  • 128
  • Comments are not for extended discussion; this conversation has been [moved to chat](https://chat.stackoverflow.com/rooms/192364/discussion-on-question-by-splatten-c-operator-overloading-where-is-the-dat). – Samuel Liew Apr 25 '19 at 12:19

2 Answers2

3

You need to arrange things so operator[](const char* cpszLabel) returns a reference to something in your class.

int& operator[](const char* cpszLabel);

is probably a better prototype.

You can then modify that "something" in your class via that reference. To be honest though what you want can be achieved with

typedef std::map<std::string, int> myclass;

and most folk don't bother with the typedef, especially now that we have auto. If you want to use a std::map as a member variable in the class (in order to reduce functionality &c.), then the following is a starting point:

class myclass
{
    std::map<std::string, int> m_data;
public:
    int& operator[](const char* cpszLabel)
    {
        return m_data[cpszLabel];
    }
};
Bathsheba
  • 231,907
  • 34
  • 361
  • 483
2

In a["test"] = 123;, the "receiver" of the assignment is the object that's returned from the lookup, which is a string.
You can't overload string's assignment operator.

But, as is well known, every problem can be solved by introducing a level of indirection.

You can store a type of your own instead of std::string, and let that handle the conversion.

A very small example as illustration:

struct Data
{
    template<typename T>
    Data& operator=(const T& rhs)
    {
        std::ostringstream os;
        os << rhs;
        value = os.str();
        return *this;
    }
    operator const char*() const { return value.c_str(); }
    std::string value;
};

struct Container
{
    Data& operator[] (const std::string& s) { return table[s]; }
    std::map<std::string, Data> table;
};

int main()
{
    Container cont;
    cont["foo"] = "bar";
    cont["baz"] = 123;
    cont["goo"] = 5.5;
    for (auto v: cont.table)
    {
        std::cout << v.first << " --> " << v.second << '\n';
    }
}

Output:

baz --> 123
foo --> bar
goo --> 5.5
molbdnilo
  • 64,751
  • 3
  • 43
  • 82