Que veux dire ce message d'erreur?
error: call of overloaded ‘setval(int)’ is ambiguous
huge.cpp:18: note: candidates are: void huge::setval(unsigned int)
huge.cpp:28: note: void huge::setval(const char*)
Mon code ressemble à ceci:
#include <iostream>
#define BYTES 8
using namespace std ;
class huge {
private:
unsigned char data[BYTES];
public:
void setval(unsigned int);
void setval(const char *);
};
void huge::setval(unsigned int t) {
for(int i = 0; i< BYTES ; i++) {
data[i] = t;
t = t >> 1;
}
}
void huge::setval(const char *s) {
for(int i = 0; i< BYTES ; i++)
data[i] = s[i];
}
int main() {
huge p;
p.setval(0);
return 0;
}
Le littéral 0
a deux significations en C++.
D'une part, c'est un entier avec la valeur 0.
En revanche, il s'agit d'une constante pointeur nul.
Comme votre fonction setval
peut accepter un int
ou un char*
, le compilateur ne peut pas décider de la surcharge que vous vouliez dire.
La solution la plus simple consiste à simplement lancer le 0
au bon type.
Une autre option est de s'assurer que la surcharge int
est préférée, par exemple en faisant de l'autre un modèle:
class huge
{
private:
unsigned char data[BYTES];
public:
void setval(unsigned int);
template <class T> void setval(const T *); // not implemented
template <> void setval(const char*);
};
La solution est très simple si l'on considère le type de la valeur constante, qui devrait être "unsigned int" au lieu de "int".
Au lieu de:
setval(0)
Utilisation:
setval(0u)
Le suffixe "u" indique au compilateur qu'il s'agit d'un entier non signé. Ensuite, aucune conversion ne serait nécessaire et l'appel sera sans ambiguïté.
remplacez p.setval(0);
par ce qui suit.
const unsigned int param = 0;
p.setval(param);
De cette façon, il sait avec certitude de quel type est la constante 0.
Utilisation
p.setval(static_cast<const char *>(0));
ou
p.setval(static_cast<unsigned int>(0));
Comme indiqué par l'erreur, le type de 0
est int
. Cela peut tout aussi facilement être converti en unsigned int
ou un const char *
. En effectuant le cast manuellement, vous indiquez au compilateur la surcharge que vous souhaitez.
Convertissez la valeur pour que le compilateur sache quelle fonction appeler:
p.setval(static_cast<const char *>( 0 ));
Notez que vous avez un défaut de segmentation dans votre code après l'avoir compilé (selon la fonction que vous vouliez vraiment appeler).
C'est ambigu car un pointeur n'est qu'une adresse, donc un int peut également être traité comme un pointeur - 0 (un int) peut être converti en entier non signé ou char * tout aussi facilement.
La réponse courte est d'appeler p.setval () avec quelque chose qui est sans ambiguïté l'un des types pour lesquels il est implémenté: unsigned int ou char *. p.setval (0U), p.setval ((unsigned int) 0) et p.setval ((char *) 0) seront tous compilés.
C'est généralement une bonne idée de rester en dehors de cette situation en premier lieu, cependant, en ne définissant pas les fonctions surchargées avec des types similaires.