2011-10-21 12 views
6

tengo un problema que cuando uso algo como esto:Cómo devolver "no encontrado" cuando el valor de retorno es referencia constante

const MyList& my_list = getListForThisRegion(/*region ID, ...*/); 

No sé lo que para volver cuando no se encuentra ningún valor.

Mi problema es que me gustaría tener una forma de señal (al devolver el valor de getListForThisRegion) "valor no encontrado" a la persona que llama. Si devolviera un puntero, podría devolver nullptr, pero no sé cómo hacerlo con las referencias. Todo lo que puedo pensar es tener algún miembro estático not_found de tipo MyList, y devolverle una referencia, pero parece feo.

Y sí, no puedo devolver el valor porque las listas son "gordas" y de uso frecuente.

EDIT: toneladas de respuestas excelentes, pero la excepción no es una solución aceptable porque el número de veces que se aumentará es alto (el porcentaje nbNotFound/nbCalls es alto).
EDIT2: con respecto al impulso :: opcional: ¿qué tan complicado es dominar? Quiero decir, ¿requiere algún conocimiento no obvio (no obvio = algo que no es simplemente conocer la sintaxis)?

+3

lanzar una excepción puede ser una buena opción. – BigMike

+1

es posible que también desee ver 'boost :: optional' – Akanksh

+0

Una referencia tiene que hacer referencia a un objeto, por lo que puede lanzar una excepción o no utilizar una referencia. 'boost :: optional' es una gran opción, pero puede ser exagerado; solo usa un puntero. – GManNickG

Respuesta

7

Hay dos maneras de manejar esta idiomáticas:

  • cambiar su interfaz para devolver un tipo que tiene la capacidad para referirse a nada (por ejemplo, un puntero que puede ser nulo, un iterador a end).

O

  • una excepción si no se encuentra el elemento.

La devolución de un objeto ficticio es un poco hacky, y no se gana nada sobre devolviendo un puntero ya que todavía tiene que comprobar el resultado en contra de un valor especial (nulo o el objeto ficticio).

+3

'boost :: optional' es un buen tipo aquí. –

+0

@ edA-qamort-ora-y: eso cambiaría la semántica para devolver por valor en lugar de referencia (a menos que devuelva una referencia opcional, pero no veo qué agrega eso a un puntero). –

+0

@Mike: ¿Qué tal 'boost :: optional >'? – fredoverflow

1

Escribiría la clase de excepción (jerarquía, si es necesario) y lanzaría una excepción para tal caso.

1

Solo veo dos posibilidades: o bien tiene un miembro especial en la clase MyList declarando que una instancia es "nula" (no establecida) o puede lanzar una excepción.

+1

Tener un miembro en 'MyList' para indicar el valor nulo parece muy intrusivo. Este tipo de característica a menudo se logra mejor al envolver el objeto en otro. 'Boost.Optional ' proporciona dicho contenedor para representar un objeto que admite nulos. –

1

Puede seguir el ejemplo de std::map, e insertar una lista construida por defecto en su contenedor, y devolver una referencia a eso. Obviamente, esto depende de que no haya una diferencia semántica entre una lista predeterminada y una lista que no está allí en absoluto.

También puede agregar una función de consulta que busque una región en particular, y devuelve verdadero si tiene una lista, y de lo contrario es falso. Luego, puede lanzar una excepción en su acceso o en la seguridad sabiendo que no será una ocurrencia común.

3

¿Qué hay de reescribir la función para hacer referencia a "returnValue" donde pone la lista para devolver? Entonces la función puede devolver el valor booleano que indica encontrado/no encontrado.

bool getListForThisRegion(/*region ID, ...*/, MyList& ret_list); 
Cuestiones relacionadas