Pregunta

Estoy escribiendo una tabla hash para mi clase de estructuras de datos, y me gustaría agregar un poco de azúcar sintáctica a mi implementación.

template <typename HashedObj, typename Object>
Object & Dictionary<HashedObj, Object>::operator[](HashedObj & key)
{
  return items.lookup(key);
}

Eso funciona bien cuando hago algo como cout < < dict [" mykey "]. Pero, ¿cómo puedo hacer una asignación con los corchetes? Algo así como:

dict["mykey"] = "something";

Y no, esto no es parte de mi tarea (sin juego de palabras), solo quiero aprender C ++ un poco mejor.

¿Fue útil?

Solución

No está claro qué es exactamente lo que está preguntando aquí. El código que presentó ya admite la asignación. Simplemente hazlo y funcionará (o al menos debería compilarse). No hace absolutamente ninguna diferencia en qué lado del operador de asignación se usa su [] sobrecargado. Funcionará exactamente de la misma manera en el lado izquierdo (LHS) que en el lado derecho (RHS) de la asignación (o como un operando de <<, como en su publicación original). Su Object devuelve una referencia a un lookup, y luego la asignación real es manejada por el operador de asignación de su tipo NULL, lo que significa que el std::map en sí no está realmente involucrado en la asignación real.

La verdadera pregunta aquí es cómo quiere que su const HashedObj& actúe en ciertos casos especiales. ¿Qué sucederá si su clave no está presente en la tabla? ¿Referencia a qué HashedObj va a devolver su <=> en este caso?

Es imposible darse cuenta de lo que publicaste. Veo que devuelve una referencia, por lo que devolver <=> está fuera de cuestión. ¿Inserta un nuevo y vacío <=> para la clave dada? Si es así, entonces no tienes que hacer nada. Su <=> ya está perfectamente listo para ser utilizado en el LHS de la asignación. (Así es como <=> en <=> funciona, por cierto)

En caso de que su <=> devuelva una referencia a un " guard " <=>, debes tomar medidas especiales. Probablemente no desee asignar nada a un & Quot; guardia & Quot; objeto, por lo que debe " desactivar " su operador de asignación de alguna manera y ya está. El resto debería funcionar como está.

Si su <=> arroja una excepción en el caso de una clave inexistente, entonces debe decidir si esto es lo que desea cuando se utiliza <=> en el LHS de una asignación. Si es así, entonces no necesitas hacer nada. Si no, entonces tomará un poco de trabajo extra ...

Entonces, de nuevo, ¿qué sucede si pasa una clave inexistente a <=>?

P.S. Además, normalmente tendría más sentido declarar el <=> (y <=>) con el parámetro <=> o simplemente con el parámetro <=>. La referencia no constante, como en su ejemplo, parece extraña y puede causar problemas en algunos (en realidad, en la mayoría de los casos). Me sorprende que funcione para ti ahora ...

Otros consejos

Necesitas sobrecargar eso 2 veces. Uno que será const, que será la parte data access, y otro que devolverá una referencia, que actuará como & Quot; setter & Quot ;.

Lo que está buscando es una funcionalidad similar al operador de soporte sobrecargado en std::map. En std::map<K,V> mymap el operador de soporte realiza una búsqueda y devuelve una referencia a un objeto asociado con una clave en particular. Si el mapa no contiene ningún objeto asociado con la clave, el operador inserta un nuevo objeto en el mapa utilizando el constructor predeterminado.

Entonces, si tiene mymap[someKey], entonces llamar a someKey devolverá una referencia al valor asociado con V, o bien creará un nuevo objeto de tipo V() llamando a <=> ( el constructor predeterminado de V) y luego devuelve una referencia a ese nuevo objeto, lo que permite al llamante asignar un valor al objeto.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top