Espacios de nombres
Variantes

Resolución de sobrecarga

De cppreference.com

Para poder compilar una llamada a función, el compilador debe primero ejecutar una búsqueda de nombre, que, para funciones, puede involucrar la búsqueda dependiente de argumento, y para plantillas de función puede estar seguido de la deducción de argumentos de plantilla. Si estos pasos producen más de una función candidato, entonces se ejecuta la resolución de sobrecarga para seleccionar la función que realmente se llamará.

En general, la función candidato cuyos parámetros coincidan más cercanamente con los argumentos es la que se llamará.

Para otros contextos donde pueden aparecer los nombres de funciones sobrecargadas, véase dirección de una función sobrecargada.

Si no se puede seleccionar una función mediante la resolución de sobrecarga (p. ej., es una entidad emplantillada con una restricción fallida), no puede nombrarse o usarse de ninguna forma.

Detalles

Antes que comience la resolución de sobrecarga, las funciones seleccionadas por búsqueda de nombre y deducción de argumento de plantilla se combinan para formar el conjunto de funciones candidato (los criterios exactos dependen del contexto en el que tiene lugar la resolución de sobrecarga; véase más abajo).

Si alguna función candidato es una función miembro (estática o no estática), pero no un constructor, se trata como si tuviera un parámetro adicional (parámetro objeto implícito) que representa el objeto para el que se llaman y aparece antes del primero de los parámetros reales.

De manera similar, el objeto en el que se llama a una función miembro se antepone a la lista de argumentos como el argumento objeto implícito.

Para las funciones miembro de la clase X, el tipo del parámetro objeto implícito se ve afectado por las calificaciones-cv y las calificaciones-ref de la función miembro como se describe en funciones miembro.

Las funciones de conversión definidas por el usuario se consideran miembros del argumento objeto implícito con el fin de determinar el tipo del parámetro objeto implícito.

Las funciones miembro introducidas por una declaración using en una clase derivada se consideran miembros de la clase derivada con el fin de definir el tipo del parámetro objeto implícito.

Para las funciones miembro estáticas, se considera que el parámetro objeto implícito coincide con cualquier objeto: su tipo no se examina y no se intenta ninguna secuencia de conversión para él.

Para el resto de la resolución de sobrecarga, el argumento objeto implícito es indistinguible de otros argumentos, pero las siguientes reglas especiales se aplican al parámetro objeto implícito:

1) las conversiones definidas por el usuario no se pueden aplicar al parámetro objeto implícito;
2) los r-valores ​​se pueden vincular al parámetro objeto implícito no constante (a menos que esto sea para una función miembro calificada-ref) (desde C++11) y no afectan la clasificación de las conversiones implícitas.
struct B { void f(int); };
struct A { operator B&(); };
A a;
a.B::f(1); // ERROR: no se pueden aplicar conversiones definidas por el usuario
           // al parámetro objeto implícito
static_cast<B&>(a).f(1); // de acuerdo

Si algún candidato es una plantilla de función, sus especializaciones se generan utilizando la deducción de argumento de plantilla, y dichas especializaciones se tratan como funciones que no son de plantilla, excepto donde se especifique lo contrario en las reglas de desempate. Si un nombre se refiere a una o más plantillas de función y también a un conjunto de funciones que no son de plantilla sobrecargadas, esas funciones y las especializaciones generadas a partir de las plantillas son todas candidato.

Si una plantilla de constructor o plantilla de función de conversión tiene un especificador explicit condicional que resulta ser dependiente del valor, después de la deducción, si el contexto requiere un candidato que no es explícito y la especialización generada es explícita, se elimina del conjunto de candidatos.

(desde C++20)

El constructor de movimiento y la asignación de movimiento por defecto (defaulted) que se definen como eliminados (=delete) nunca se incluyen en la lista de funciones candidato.

Los constructores heredados de copia y movimiento no se incluyen en la lista de funciones candidato al construir un objeto de clase derivado.

Funciones candidato

El conjunto de funciones candidato y la lista de argumentos se prepara de una manera única para cada uno de los contextos donde de usa la resolución de sobrecarga:

Llamada a una función denominada

Si E en una expresión de llamada a función E(args) denomina un conjunto de funciones sobrecargadas y/o plantillas de función (pero no objetos invocables), se siguen las siguientes reglas:

  • Si la expresión E tiene la forma PA->B o A.B (donde A tiene un tipo clase cv T), entonces B es buscada como una función miembro de T. Las declaraciones de función encontradas por esa búsqueda son las funciones candidato. La lista de argumentos para la resolución de sobrecarga tiene el argumento de objeto implícito de tipo cv T.
  • Si la expresión E es una expresión primaria, el nombre es buscado siguiendo las reglas normales para llamadas a función (que pueden involucrar ADL). Las declaraciones de función encontradas por esta búsqueda son (debido a la forma en que funciona la búsqueda) o bien:
a) todas las funciones que no son miembros (en cuyo caso la lista de argumentos con el propósito de la resolución de sobrecarga es exactamente la lista de argumentos utilizada en la expresión de llamada de función), o
b) todas las funciones miembro de alguna clase T, en cuyo caso, si this está dentro del ámbito y es un puntero a T o a una clase derivada de T, *this se utiliza como el argumento objeto implícito. De lo contrario (si this no está dentro del ámbito o no apunta a T), se usa un objeto falso de tipo T como el argumento objeto implícito, y si la resolución de sobrecarga selecciona posteriormente una función miembro no estática, el programa está mal formado.

Llamada a un objeto clase

Si E en una expresión de llamada a función E(args) tiene un tipo clase cv T, entonces

  • Los operadores de llamada a función de T se obtienen mediante la búsqueda ordinaria del nombre operator() en el contexto de la expresión (E).operator(), y cada declaración encontrada se agrega al conjunto de funciones candidato.
  • Para cada función de conversión definida por el usuario no explícita en T o en una base de T (a menos que esté oculta), cuyos calificadores-cv son los mismos o mayores que los calificadores-cv de T, y donde la función de conversión convierte a:
  • puntero a función
  • referencia a puntero a función
  • referencia a función
luego una función de llamada sustituta con un nombre único cuyo primer parámetro es el resultado de la conversión, los parámetros restantes son la lista de parámetros aceptada por el resultado de la conversión, y el tipo de retorno es el tipo de retorno del resultado de la conversión, se agrega al conjunto de funciones candidato. Si esta función sustituta se selecciona mediante la resolución de sobrecarga subsiguiente, se llamará a la función de conversión definida por el usuario y luego se llamará al resultado de la conversión.

En cualquier caso, la lista de argumentos con el propósito de la resolución de sobrecarga es la lista de argumentos de la expresión de llamada a función precedida por el objeto argumento implícito E (cuando se compara con la función sustituta, la conversión definida por el usuario automáticamente convertirá el objeto argumento implícito al primer argumento de la función sustituta).

int f1(int);
int f2(float);
struct A {
    using fp1 = int(*)(int);
    operator fp1() { return f1; } // función de conversión de puntero a función
    using fp2 = int(*)(float);
    operator fp2() { return f2;