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.