web-dev-qa-db-fra.com

L'appel de la fonction surchargée est ambigu

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;
}
21
Barshan Das

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*);
};
21

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é.

13
Leonardo L.

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.

3
Null Set

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.

1
Eclipse

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).

1
Mark Loeser

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.

1
metamatt