2012-10-03 31 views
11

Sobrecargamos un operador dos veces con la misma lista de parámetros. pero con diferente tipo de retorno:operador de sobrecarga de C++ dos veces, una referencia de retorno no const y la otra referencia de referencia, ¿cuál es la preferencia?

T& operator()(par_list){blablabla}  
const T& operator()(par_list){blablabla} 

Así que cuando estoy llamando al operador(), cuya función sería llamado en base a lo preferencia o situación? Sé que si llamo() a la función const, tiene que ser la const T &.

Tengo curiosidad de cómo C++ se ocupa de tal situación y cómo funciona la preferencia predeterminada.

Gracias

+1

El término es la sobrecarga * *, y no. – chris

+2

C++ No permite la sobrecarga por tipo de devolución. Uno podría entrar en lo que 'debería/debería' hacer, pero no importará. Un truco es hacer que el método sea constante cuando el tipo de retorno es const, ya que puede estar sobrecargado. Mi memoria es el método const preferido, y no const se llama la llamada const no sería legal. – Joe

Respuesta

21

Estas funciones no se sobrecargan entre sí; tienen las mismas firmas, por lo que el intento de redefinir la misma función, que es un error. El tipo de devolución no es parte de la firma de una función. Para sobrecargar una función, debe declarar una segunda función con el mismo nombre, pero diferentes parámetros o calificadores const/volatile, es decir, calificadores en la función, no el tipo de devolución.

(No se anulan entre sí tampoco, la anulación es lo que las clases derivadas hacen a las funciones virtuales de sus clases base).

Es común definir una sobrecarga const y una no-const de una función miembro; la sobrecarga de const debe declarar la función const, no sólo el tipo de retorno:

T& operator()(par_list){blablabla} 
const T& operator()(par_list) const {blablabla} 
           ^^^^^ 

Ahora, la primera será llamado si se aplica a un ()const objeto no, y el segundo en un objeto const. Por ejemplo:

Thingy nc; 
Thingy const c; 

nc(); // calls the first (non-const) overload 
c(); // calls the second (const) overload 
+0

@ DavidRodríguez-dribeas: OK, no me di cuenta de que la "firma" incluía el tipo de devolución. ¿Hay un término oficial para "los bits que determinan qué sobrecarga elegir"? –

+0

@ DavidRodríguez-dribeas Quizás puedas aclarar esto porque parece haber cambiado desde C++ 03. '§1.3.18' parece referirse a funciones de plantilla. Pero las entradas para las funciones sin plantilla (gratuita o miembro) no hacen mención de los valores devueltos. Tampoco las entradas para las especializaciones de función de la plantilla. – juanchopanza

+0

@juanchopanza: Tiene razón, eliminando el comentario. Mike, una lectura cuidadosa del estándar indica que para las plantillas de funciones (como menciona Juancho) el tipo de devolución es parte de la firma. Para las funciones regulares, la firma no incluye el tipo de devolución. C++ 03 tiene una nota al pie: * Las firmas de función no incluyen el tipo de devolución, porque eso no participa en la resolución de sobrecarga. * Perdón por introducir confusión en la respuesta :) –

3

No se puede sobrecargar una función/método basado en el tipo de retorno. Esperaría que el compilador arrojara un error aquí. Lo que puede hacer es especificar el método en sí mismo como un método const, utilizando

const T& operator()(par_list) const {blahblah} 

El const calificador no sólo significa que este puede ser llamado en un receptor const, pero también se utiliza en la resolución de sobrecarga. Esto sucede porque afecta el parámetro implícito *this que se pasa al método; un método const usa un calificador const en *this, y los calificadores const se tienen en cuenta durante la resolución de sobrecarga.

1

La forma de definir sus operadores, de ninguna manera el compilador puede decidir a qué operador() llamar. La sobrecarga de funciones (y operadores) solo puede hacerse en el tipo de argumentos, nunca en el tipo de devolución. Y, de hecho, tendrá un error de compilación tan pronto como defina el segundo, el compilador teniendo en cuenta que está redefiniendo la misma función/operador.

Sin embargo, la siguiente es común (y probablemente lo que tiene):

T& operator()(par_list){blablabla} 
const T& operator()(par_list) const {blablabla} 

existe este "const" adicional después de la lista de argumentos, ya que está definiendo las funciones miembro y funciones miembro no estática tienen una implícita argumento oculto: el "este" puntero a la instancia de la clase. La palabra clave "const" allí indica si este puntero oculto está en una instancia const o no.Este argumento participa en la resolución de sobrecarga y es en este caso lo que el compilador usa para elegir qué versión del operador usar.

Así:

class A { 
    T& operator()() { ... } 
    const T& operator()() const { .... } 
}; 

A a; 
const A& ca(a); 
a(); -> returns a T& 
ca(); -> returns a const T& 
Cuestiones relacionadas