error: call of overloaded '...' is ambiguous

1. error: call of overloaded '...' is ambiguous

Perfil removido
removido

(usa Nenhuma)

Enviado em 13/01/2018 - 19:27h

Boa tarde, estou apredendo polimorfismo de sobrecarga porém o compilador está retornando esses erros:

||=== Build: Debug in Sobrecarga Ex.A13a (compiler: GNU GCC Compiler) ===|
/home/TheBugLog/Documents/POO/Sobrecarga Ex.A13a/main.cpp||In function ‘int main()’:|
/home/TheBugLog/Documents/POO/Sobrecarga Ex.A13a/main.cpp|11|error: call of overloaded ‘reagir(int, double)’ is ambiguous|
include/Cachorro.h|19|note: candidate: void Cachorro::reagir(short int, short int)|
include/Cachorro.h|20|note: candidate: void Cachorro::reagir(short int, float)|
||=== Build failed: 1 error(s), 0 warning(s) (0 minute(s), 0 second(s)) ===|


Segue o código:

#ifndef CACHORRO_H
#define CACHORRO_H

#include <string>
#include "Animal.h"

class Cachorro : public Animal{

public:

void locomover();
void alimentar();
void emitirSom();

public:

void reagir(bool dono);
void reagir(std::string frase);
void reagir(short hora, short minutos);
void reagir(short idade, float peso);
};

#endif // CACHORRO_H



#include <iostream>
#include "Cachorro.h"

void Cachorro::locomover(){

std::cout << "Correndo..." << std::endl;
}

void Cachorro::alimentar(){

std::cout << "Comendo ração..." << std::endl;
}

void Cachorro::emitirSom(){

std::cout << "Latindo..." << std::endl;
}

//Diferentes reações do cachorro

void Cachorro::reagir(bool dono){

if(dono==true){

std::cout << "Abanando Rabo" << std::endl;

}else{

std::cout << "Rosnando" << std::endl;
}
}

void Cachorro::reagir(std::string frase){

if(frase.compare("Vem aqui")==0){

std::cout << "Abanando rabo e feliz" << std::endl;

}else if(frase.compare("Vem aqui cachorro feio")){

std::cout << "Rosnando e abanando rabo" << std::endl;

}else{

std::cout << "Ignorando" << std::endl;
}
}

void Cachorro::reagir(short hora, short minutos){

if(hora<=12 && minutos<=59){

std::cout << "Abanando rabo e alegre" << std::endl;

}else if(hora<=18 && minutos<=59){

std::cout << "Abanando rabo e latindo" << std::endl;

}else{

std::cout << "Ignorando" << std::endl;
}
}

void Cachorro::reagir(short idade , float peso){

if(idade<=2 && peso <= 0.9){

std::cout << "Abanando rabo (novo e leve)" << std::endl;

}else if(idade>=3 && peso <= 0.9){

std::cout << "Abanando rabo e latindo (velho e leve)" << std::endl;

}else if(idade<=2 && peso >= 1){

std::cout << "Abanando rabo e rosnando (novo e pesado)" << std::endl;

}else{

std::cout << "Ignorando (velho e pesado)" << std::endl;
}
}



  


2. Re: error: call of overloaded '...' is ambiguous

Perfil removido
removido

(usa Nenhuma)

Enviado em 13/01/2018 - 19:55h

Blz! Consegui dar uma volta em cima dos erros que estavam aparecendo mudando os tipos primitivos para int de um dos metodos poliformicos (porém não sei os motivos dos erros passados):


....code

void Cachorro::reagir(int hora, int minutos){

if(hora<=12 && minutos<=59){

std::cout << "Abanando rabo e alegre" << std::endl;

}else if(hora<=18 && minutos<=59){

std::cout << "Abanando rabo e latindo" << std::endl;

}else{

std::cout << "Ignorando" << std::endl;
}
}

void Cachorro::reagir(short idade , float peso){

if(idade<=2 && peso <= 0.9){

std::cout << "Abanando rabo (novo e leve)" << std::endl;

}else if(idade>=3 && peso <= 0.9){

std::cout << "Abanando rabo e latindo (velho e leve)" << std::endl;

}else if(idade<=2 && peso >= 1){

std::cout << "Abanando rabo e rosnando (novo e pesado)" << std::endl;

}else{

std::cout << "Ignorando (velho e pesado)" << std::endl;
}
}
.....code



No programa principal:


#include <iostream>
#include "Cachorro.h"

int main(){

Cachorro *spaceDogo=new Cachorro;

spaceDogo->reagir(false);
spaceDogo->reagir("Vem aqui");
spaceDogo->reagir(9,30);
spaceDogo->reagir(5,5.8);

return 0;
}


Saida na execução:


Rosnando
Abanando rabo
Abanando rabo e alegre
Abanando rabo e alegre


Perceba que na última imprensão ele imprimiu algo que esta em outra função, ele deveria ter imprimido "Ignorando (velho e pesado)" e não "Abanando rabo e alegre", mais agora porque? É um "bug"?


3. Re: error: call of overloaded '...' is ambiguous

Fernando
phoemur

(usa Debian)

Enviado em 14/01/2018 - 00:24h

Olha, isso não é um bug, na verdade é consequência de um programa repleto de práticas por assim dizer, sub-ótimas...
Tem muitas coisas a dizer, por exemplo alocação de memória sem liberar, causando vazamento de memória (new sem o delete), entre outras coisas...

No caso que você disse, o problema está na inferência de tipos. Quando o compilador vai fazer a resolução dos overloads para decidir qual função vai chamar.
Veja aqui:
http://www.dcs.bbk.ac.uk/~roger/cpp/week20.htm

Especificamente quando você chama
spaceDogo->reagir(5,5.8);

O primeiro parâmetro (5) por default é um rvalue do tipo int, e o segundo parãmetro (5.8) por default é um rvalue do tipo double

Por mais estranho que possa paracer, é isso mesmo, veja aqui no ISO standard:

2.13.3 Floating literals The type of a floating literal is double unless explicitly specified by a suffix. The suffixes f and F specify float, the suffixes l and L specify long double. If the scaled value is not in the range of representable values for its type, the program is ill-formed.


Ou seja, você está chamando reagir(int, double)
Porém no seu código são definidos:
1-) reagir(int, int)
2-) reagir(short, float)
3-) reagir(string)
4-) reagir(bool)

Como não há uma correspondência exata, o compilador vai fazer uma "conversão" implícita.
Simplificando grotescamente: (int, double) para (short, float) são duas "conversões", enquanto (int, double) para (int, int) é apenas uma conversão, ou seja, essa opção é considerada mais adequada do ponto de vista do compilador, apesar de ser estranha à primeira vista.
Mas é assim que funciona e está definido no padrão da linguagem.

A ordem de escolha é esta:

1-) An exact match, e.g. argument is a double and parameter is a double
2-) A promotion
3-) A standard type conversion
4-) A constructor or user-defined type conversion


Ou seja, no caso (int, double) para (short, float) são duas "conversões" que ainda por cima são "narrowing" (tem potencial de truncar/overflow) pois short tem 16 bits e int 32, assim como float 32 e double 64, e por isso vâo lá pro fim da fila na hora da escolha.

Em resumo, não tem nada de estranho nesse comportamento.
Espero que tenha entendido o que aconteceu.
Para mais detalhes:
http://en.cppreference.com/w/cpp/language/overload_resolution

Experimenta chamar assim pra ver se funciona (o f indica float):
spaceDogo->reagir(5,5.8f); 


De qualquer forma esses overloads ambíguos, justamente por este motivo, são considerados uma má prática de programação e devem ser evitados.


4. Re: error: call of overloaded '...' is ambiguous

Paulo
paulo1205

(usa Ubuntu)

Enviado em 14/01/2018 - 21:56h

Excelente explicação, Phoemur! +1!






Patrocínio

Site hospedado pelo provedor RedeHost.
Linux banner

Destaques

Artigos

Dicas

Tópicos

Top 10 do mês

Scripts