error: la llamada de la ‘función (x)’ sobrecargada es ambigua | Ambigüedad en la sobrecarga de funciones en C++

Requisito previo: sobrecarga de funciones en C++

La sobrecarga de funciones es una característica de la programación orientada a objetos en la que dos o más funciones pueden tener el mismo nombre pero diferentes parámetros. Se dice que dos o más funciones están sobrecargadas si difieren en cualquiera de los siguientes:

  1. El número de argumentos.
  2. Orden de los argumentos.
  3. Tipo de argumentos.

En la sobrecarga de funciones, a veces puede ocurrir una situación en la que el compilador no puede elegir entre dos funciones sobrecargadas correctamente. Se dice que esta situación es ambigua. 

Las declaraciones ambiguas son declaraciones que generan errores y los programas que contienen ambigüedad no se compilarán. Las conversiones automáticas de tipo son la causa principal de la ambigüedad. En C++, el tipo de argumento que se usa para llamar a la función se convierte en el tipo de parámetros definidos por la función. 

Entendamos la ambigüedad a través de algunos ejemplos.

La llamada de la función sobrecargada es ambigua

Ejemplo 1: la llamada de ‘test(char)’ sobrecargada es ambigua

Cómo ocurre esta ambigüedad:
A continuación se muestra el programa C++ para demostrar la ambigüedad.

C++

// C++ program to implement
// the above approach
#include <iostream>
using namespace std;
 
// Overloaded Function with
// float type parameter
void test(float f)
{
    cout << "Overloaded Function with float "
         << "parameter being called";
}
 
// Overloaded Function with
// double type parameter
void test(double d)
{
    cout << "Overloaded Function with double "
         << "parameter being called";
}
 
// Driver code
int main()
{
    // Overloaded Function called
    // with char type value
    test('a');
 
    return 0;
}

Producción:

prog.cpp: En la función ‘int main()’:

prog.cpp:25:11: error: la llamada de ‘test(char)’ sobrecargada es ambigua

  prueba(‘a’);

          ^

prog.cpp:8:6: nota: candidato: prueba nula (flotante)

prueba de vacío (flotante f)  

     ^

prog.cpp:15:6: nota: candidato: prueba nula (doble)

prueba nula (doble d)  

     ^

Por qué se produce la ambigüedad:

 Cuando no hay una coincidencia de tipo exacta, el compilador busca la coincidencia más cercana. La coincidencia más cercana para “test(‘a’);” será “void test(int a)”, ya que no está presente, void test(doble d) y void (float f) causará ambigüedad. Ambas son conversiones válidas. Esta confusión hace que se muestre un mensaje de error y evita que el programa se compile.

Nota:
De acuerdo con la especificación del lenguaje C, cualquier tipo de entero más corto que int, por ejemplo, bool, char, short se convierte implícitamente a int.

Un char encaja en un int sin desbordarse ni perder precisión, lo que explica el primer código. Pero un int no encaja en char (desbordamiento), double (falta de precisión) o int* (tipo incompatible).

Cómo resolver la ambigüedad:

Hay dos formas de resolver esta ambigüedad:

  1. Typecast char para flotar.
  2. Elimine cualquiera de las funciones de generación de ambigüedad float o double y agregue la función sobrecargada con un parámetro de tipo int.

Solución 1: Typecast char para flotar

A continuación se muestra el programa C++ para demostrar cómo el encasillamiento de char para flotar resuelve el problema.

C++

// C++ program to implement
// the above approach
#include <iostream>
using namespace std;
 
// Overloaded Function with
// float type parameter
void test(float f)
{
    cout << "Overloaded Function with float "
         << "parameter being called";
}
 
// Overloaded Function with
// double type parameter
void test(double d)
{
    cout << "Overloaded Function with double "
         << "parameter being called";
}
 
// Driver code
int main()
{
    // Overloaded Function called
    // with char type value
    // typecasted to float
    test((float)('a'));
 
    return 0;
}
Producción

Overloaded Function with float parameter being called

Solución 2: elimine cualquiera de las funciones de generación de ambigüedad float o double y agregue la función sobrecargada con un parámetro de tipo int.

A continuación se muestra el programa C++ para demostrar cómo agregar una función de sobrecarga con un parámetro de tipo int puede resolver la ambigüedad en el código anterior.

C++

// C++ program to implement
// the above approach
#include <iostream>
using namespace std;
 
// Overloaded function with
// int type parameter
void test(int f)
{
    cout << "Overloaded Function with "
         << "int type parameter called";
}
 
// Overloaded function with
// double type parameter
void test(double d)
{
    cout << "Overloaded Function with "
         << "double type parameter called";
}
 
// Driver code
int main()
{
    // Overloaded Function called
    // with char type value
    test('a');
    return 0;
}
Producción

Overloaded Function with int type parameter called

Ejemplo 2: la llamada de ‘prueba (flotante)’ sobrecargada es ambigua

Cómo ocurre esta ambigüedad:
a continuación se muestra el programa C++ para demostrar lo que sucederá en el escenario cuando se use el tipo de valor flotante para llamar a la función sobrecargada y no haya ninguna función con los parámetros flotante o doble.

C++

// C++ program to implement
// the above approach
#include <iostream>
using namespace std;
 
// Overloaded function with
// int type parameter
void test(int f)
{
    cout << "Overloaded Function with "
         << "int type parameter called";
}
 
// Overloaded function with
// long type parameter
void test(long l)
{
    cout << "Overloaded Function with "
         << "long type parameter called";
}
 
// Driver code
int main()
{
    // Overloaded Function called
    // with float type value
    test(2.5f);
    return 0;
}

Producción:

prog.cpp: En la función ‘int main()’:

prog.cpp:25:12: error: la llamada de ‘test(float)’ sobrecargada es ambigua

  prueba (2.5f);

           ^

prog.cpp:8:6: nota: candidato: prueba nula (int)

prueba nula (int f)  

     ^

prog.cpp: 15: 6: nota: candidato: prueba nula (int largo)

prueba de vacío (d larga)  

     ^

Por qué ocurre la ambigüedad:
el código anterior arrojará un error porque la llamada a la función test(2.5f) buscará la función flotante, si no está presente, solo se promueve a doble, pero no hay una definición de función con el tipo de parámetro doble o flotante.

A menos que se especifique explícitamente, todos los literales de punto flotante son automáticamente de tipo doble en C++. En esta ambigüedad, la variable de tipo flotante se convierte implícitamente a tipo doble y si no hay una función sobrecargada de tipo flotante o doble y la función se llama con un valor flotante, el programa arrojará un error.

Nota:
El flotante se convierte en doble en las siguientes situaciones:

  • El flotador es un argumento para una llamada de función, correspondiente a un tipo de parámetro doble en un prototipo de función.
  • Un operador binario tiene double y float como dos tipos de argumentos.
  • Un operador condicional tiene double y float como segundo y tercer operando.
  • El valor flotante se convierte al doble.
  • El valor flotante se asigna a doble.

Cómo resolver la ambigüedad:

Hay dos formas de resolver la ambigüedad:

  1. Typecast float a int.
  2. Elimine una de las funciones de generación de ambigüedad int o long y agregue una función sobrecargada con un parámetro de tipo doble.

Solución 1: Typecast float a int

A continuación se muestra el programa C++ para demostrar cómo el encasillamiento de float a int resuelve el problema.

C++

// C++ program to implement
// the above approach
#include <iostream>
using namespace std;
 
// Overloaded function with
// int type parameter
void test(int f)
{
    cout << "Overloaded Function with "
         << "int type parameter called";
}
 
// Overloaded function with
// long type parameter
void test(long l)
{
    cout << "Overloaded Function with "
         << "long type parameter called";
}
 
// Driver code
int main()
{
    // Overloaded Function called
    // with float type value
    test((int)(2.5f));
    return 0;
}
Producción

Overloaded Function with int type parameter called

Solución 2: elimine una de las funciones de generación de ambigüedad int o long y agregue una función sobrecargada con un parámetro de tipo doble.

A continuación se muestra el programa C++ para demostrar cómo resolver esta ambigüedad agregando una función sobrecargada con parámetros de tipo doble.

C++

// C++ program to implement
// the above approach
#include <iostream>
using namespace std;
 
// Overloaded function with
// int type parameter
void test(double d)
{
    cout << "Overloaded Function with "
         << "double type parameter called";
}
 
// Overloaded function with
// long type parameter
void test(long l)
{
    cout << "Overloaded Function with "
         << "long type parameter called";
}
 
// Driver code
int main()
{
    // Overloaded Function called
    // with float type value
    test(2.5f);
    return 0;
}
Producción

Overloaded Function with double type parameter called

Llamada de función sobrecargada con diferente número de argumentos

Redefinición de la función ‘void test(int, int):
Veamos otro escenario de ambigüedad donde la ambigüedad ocurre cuando se trata de dos parámetros y uno de los parámetros tiene un valor predeterminado establecido.

C++

// C++ program to implement
// the above approach
#include <iostream>
using namespace std;
 
// Overloaded Function with
// one int type parameter
void test(int i)
{
    cout << "Overloaded function with "
         << "one int parameter called " << endl;
    cout << i;
}
 
// Overloaded Functionwith
// two int type parameter
void test(int i, int j = 5)
{
    int sum;
    sum = i + j;
 
    cout << "Overloaded function with "
         << "two int parameter called " << endl;
    cout << sum;
}
 
// Driver code
int main()
{
    // Overloaded Function called
    // with two int values
    // Unambiguous call
    test(10, 11);
 
    // Overloaded Function called
    // with one int value
    // Ambiguous call
    test(10);
 
    return 0;
}

Producción:

prog.cpp: en la función ‘prueba de anulación (int, int)’:

prog.cpp:17:6: error: redefinición de ‘prueba nula (int, int)’

prueba de vacío (int i, int j = 5)  

     ^

prog.cpp:8:6: nota: ‘prueba nula (int, int)’ definida anteriormente aquí

prueba nula (int i, int j)  

     ^

prog.cpp: En la función ‘int main()’:

prog.cpp:35:10: error: muy pocos argumentos para la función ‘void test(int, int)’

  prueba(10);

         ^

prog.cpp:8:6: nota: declarado aquí

prueba nula (int i, int j)  

     ^

Por qué se produce la ambigüedad:

Aquí, en la declaración de llamada inequívoca test(10, 11) se especifican dos argumentos, por lo que no hay ambigüedad. En la instrucción de llamada ambigua test(10), el compilador se confunde sobre si llamar a la primera función test() que toma un argumento o llamar a la segunda función test() con dos argumentos, de los cuales uno es el predeterminado. Esto hace que el programa arroje un error.

Cómo resolver la ambigüedad:

Una solución para resolver la ambigüedad es eliminar el valor predeterminado de la función sobrecargada con dos parámetros int. A continuación se muestra el programa C++ para demostrar el enfoque anterior:

C++

// C++ program to implement
// the above approach
#include <iostream>
using namespace std;
 
// Overloaded Function with
// one int type parameter
void test(int i)
{
    cout << "Overloaded function with "
         << "one int parameter called " << endl;
    cout << i << endl;
}
 
// Overloaded Functionwith
// two int type parameter
void test(int i, int j)
{
    int sum;
    sum = i + j;
 
    cout << "Overloaded function with "
         << "two int parameter called " << endl;
    cout << sum << endl;
}
 
// Driver code
int main()
{
    // Overloaded Function called
    // with two int values
    // Unambiguous call
    test(10, 11);
 
    // Overloaded Function called
    // with one int value
    // Ambiguous call
    test(10);
 
    return 0;
}
Producción

Overloaded function with two int parameter called 
21
Overloaded function with one int parameter called 
10

Complejidad de tiempo: O(1)

Espacio Auxiliar: O(1)

Publicación traducida automáticamente

Artículo escrito por sathiyamoorthics19 y traducido por Barcelona Geeks. The original can be accessed here. Licence: CCBY-SA

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *