Diese Frage könnte in Bezug auf C++ im Allgemeinen besser gestellt werden, aber da ich gcc unter Linux verwende, ist das der Kontext. folgendes Programm vor:C++: Warum bevorzugt gcc beim Zugriff auf operator [] nicht-const über const?
#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;
}
Wenn das Programm ausgeführt wird, ist die Ausgabe:
operator[] with key 1 called
operator[] with key 1 called
first one: one
Was Ich mag würde, ist der Compiler wählt die operator[]const
Methode stattdessen in dem zweiten Aufruf zu haben. Der Grund dafür ist, dass der Aufruf von operator[]
ohne die Verwendung von dict ["1"] dazu führt, dass die interne Karte die Daten erzeugt, die nicht existieren, selbst wenn das einzige, was ich wollte, eine Debugausgabe ist, was natürlich ist ein schwerwiegender Anwendungsfehler
Das Verhalten ich suche so etwas wie der C# Index-Operator sein würde, die ein Get- und Set-Betrieb hat und wo Sie eine Ausnahme auslösen könnten, wenn der Getter etwas zuzugreifen versucht, der nicht existiert:
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;
}
}
}
So frage ich mich, warum der gcc den nichtkonstanten Aufruf über den Const-Aufruf bevorzugt, wenn nicht-const-Zugriff nicht erforderlich ist.
Es wird nicht-const aufgerufen, es sei denn, die einzige verfügbare Version ist const und führt nicht zum Fehler "discard qualifiers". Offensichtlich weiß der Compiler, welche Versionen existieren, also könnte er auch die verwenden, die meine Daten nicht zerstört. Ich persönlich denke das ist ein schlechtes Compilerverhalten, also erleuchte mich. Warum haben sie es so gemacht, wenn umgekehrt (lieber nicht-const) sicherer AFAICT ist? – JonasW
scheint sicherer, aber es ist nicht zu logisch, die * beste * Übereinstimmung ist die nicht const, wie es von genau der gleichen Art und Konstanz ist. Danach kann es nach anderen Übereinstimmungen suchen. Im Allgemeinen führt dies zu der geringsten Überraschung. Wenn Sie const Sicherheit wollen, müssen Sie es anweisen, es zu verwenden –