Esta pregunta podría ser más adecuada en relación con C++ en general, pero como estoy usando gcc en Linux ese es el contexto. Considere el siguiente programa:C++: ¿Por qué gcc prefiere no const sobre const al acceder al operador []?
#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;
}
Al ejecutar el programa, la salida es:
operator[] with key 1 called
operator[] with key 1 called
first one: one
Lo que me gustaría es tener el compilador elegir el método operator[]const
lugar en la segunda llamada. La razón es que sin haber usado dict ["1"] antes, la llamada a operator[]
hace que el mapa interno cree los datos que no existen, incluso si lo único que quería era hacer algún tipo de depuración, que por supuesto es un error de aplicación fatal.
El comportamiento Busco sería algo así como el operador de índice C#, que tiene un encuentro y una operación de conjunto y donde se puede lanzar una excepción si el comprador intenta acceder a algo que no existe:
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;
}
}
}
Por lo tanto, me pregunto por qué el gcc prefiere la llamada no const a través de la llamada const cuando no se requiere acceso no const.
Llamará a no-const a menos que la única versión disponible sea const y que no dé como resultado el error de "descarte de calificadores". Obviamente, el compilador sabe qué versiones existen, así que podría usar una que no destruya mis datos. Personalmente creo que esto es un mal comportamiento del compilador, así que infórmenme. ¿Por qué lo hicieron de esta manera cuando a la inversa (preferir no const) es una AFAICT más segura? – JonasW
puede parecer más seguro, pero no es demasiado lógico, la * mejor * coincidencia es la no const porque es exactamente del mismo tipo y constness. Después de eso, puede buscar otras coincidencias. En general, esto resulta en la menor sorpresa. Si desea obtener seguridad, tiene que dirigirla para usarla –