Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C++: Why does gcc prefer non-const over const when accessing operator[]?

Tags:

c++

gcc

constants

This question might be more appropriately asked regarding C++ in general, but as I am using gcc on linux that's the context. Consider the following program:

#include <iostream>
#include <map>
#include <string>

using namespace std;

template <typename TKey, typename TValue>
class Dictionary{
    public:
    map<TKey, TValue> internal;

    TValue & operator[](TKey const & key)
    {
        cout << "operator[] with key " << key << " called " << endl;
        return internal[key];
    }

    TValue const & operator[](TKey const & key) const
    {
        cout << "operator[] const with key " << key << " called " << endl;
        return internal.at(key);
    }

};

int main(int argc, char* argv[])
{
    Dictionary<string, string> dict;
    dict["1"] = "one";
    cout << "first one: " << dict["1"] << endl;

    return 0;
}

When executing the program, the output is:

   operator[] with key 1 called 
   operator[] with key 1 called 
   first one: one

What I would like is to have the compiler choose the operator[]const method instead in the second call. The reason is that without having used dict["1"] before, the call to operator[] causes the internal map to create the data that does not exist, even if the only thing I wanted was to do some debugging output, which of course is a fatal application error.

The behaviour I am looking for would be something like the C# index operator which has a get and a set operation and where you could throw an exception if the getter tries to access something that doesn't exist:

class MyDictionary<TKey, TVal>
{
    private Dictionary<TKey, TVal> dict = new Dictionary<TKey, TVal>();
    public TVal this[TKey idx]
    {
        get
        {
            if(!dict.ContainsKey(idx))
                throw KeyNotFoundException("...");

            return dict[idx];
        }
        set
        {
            dict[idx] = value;
        }
    }
}

Thus, I wonder why the gcc prefers the non-const call over the const call when non-const access is not required.

like image 598
JonasW Avatar asked Mar 17 '10 20:03

JonasW


1 Answers

You can't get the effect you want. When dict is non-const, it will call the non-const version of operator[].

C# is superior in this case because it can determine whether 'dict[n]' is part of an assignment. C++ cannot do this.

like image 78
richb Avatar answered Nov 20 '22 03:11

richb