Pregunta Eliminando la función sobrecargada. C ++ 11. Llamada de sobrecarga ... es ambigua


Hay una función global (solo ejemplo):

void func( int i )
{
    std::cout << i + 100 << std::endl;
}

Supongo que llamar a esta función con argumento char no tiene ningún sentido, así que utilizo delete:

void func(char) = delete;

Así que espero que las siguientes llamadas sean posibles:

func(1);
func(3.1);
func(true);

Y call with char argument debería ser forbiden:

func('a');

Pero eso no es verdad. Cuando llamas func('a') Me sale como esperaba

error: use of deleted function ‘void func(char)’

Pero durante la llamada func(2.3) Yo obtengo:

error: call of overloaded ‘func(double)’ is ambiguous

¿Por qué obtengo este error? Sin eliminar la función con char argumentos double se convirtió a int y func (int) se llamó, ¿por qué ahora está prohibido?


8
2017-12-28 17:34


origen


Respuestas:


Cuando usted llama

func(2.3)

pasas una double a la función. La lista de candidatos contiene ambos  func(int) y func(char), como sucede la resolución de sobrecarga antes de  delete patadas en:

Si la función está sobrecargada, la resolución de sobrecarga tiene lugar primero, y el programa solo está mal formado si se seleccionó la función eliminada.  Ref: cppreference.com, ver La respuesta de Avishai para presupuestos estándar precisos.

Ahora double se puede convertir tanto a char y int, de ahí la ambigüedad.

Sin eliminar la función con char argumentos double se convirtió a int y func (int) se llamó, ¿por qué ahora está prohibido?

Obtiene un error de ambigüedad incluso sin deleteing la char versión, vea en vivo aquí. Por supuesto, si solo defines el func(int), entonces no habrá ambigüedad por lo double felizmente se convertirá en un int.


12
2017-12-28 17:44



Cada vez que se pasa una coincidencia no exacta para un parámetro de función, se debe realizar una conversión. Cuando tiene dos funciones, independientemente de si se elimina una, aún participan en la resolución de sobrecarga. El compilador elige la mejor coincidencia, luego genera una llamada a ella, o falla si la función es inaccesible o eliminada.

Para que la resolución de sobrecarga funcione, hace que un conjunto de funciones candidatas vea cuál tiene la ruta de conversión más corta al conjunto de parámetros. En cuanto a las reglas, todos los tipos numéricos incorporados son una conversión "igual". Por lo tanto, si llama con 2.5, que es un doble, debe convertir y puede convertir igualmente a un OR O a un int, con el mismo ranking, por lo que la llamada es ambigua.


1
2017-12-28 17:50



Todavía es ambiguo, ya que el compilador intenta resolver la sobrecarga antes de buscar funciones eliminadas. Ver:

§8.4.3 Definiciones eliminadas

Un programa que se refiere a una función eliminada implícita o explícitamente, que no sea para declararlo, está mal formado.   [   Nota:   Esto incluye llamar a la función implícita o explícitamente y formar un puntero o puntero a miembro   a la función. Se aplica incluso para referencias en expresiones que no son potencialmente evaluadas. Si una función   está sobrecargado, se hace referencia solo si la función se selecciona mediante resolución de sobrecarga.   - nota final   ]

§13.3.3.1 Secuencias de conversión implícitas:

Las secuencias de conversión implícitas solo se refieren al tipo, cv-calificación y categoría de valor de   el argumento y cómo se convierten para que coincidan con las propiedades correspondientes del parámetro. Otro   propiedades, como la duración, clase de almacenamiento, alineación, accesibilidad del argumento, si el argumento   es un campo de bits, y si se borra una función (8.4.3), se ignoran. Entonces, aunque una conversión implícita   la secuencia se puede definir para un par argumento-parámetro dado, la conversión del argumento al   el parámetro aún podría estar mal formado en el análisis final.


0
2017-12-28 17:49