Вызов перегруженной функции неоднозначен

Что означает это сообщение об ошибке?

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

Мой код выглядит следующим образом:

#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;
}

Ответы

Ответ 1

Литерал 0 имеет два значения в С++.
С одной стороны, это целое число со значением 0.
С другой стороны, это константа нулевого указателя.

Поскольку ваша функция setval может принимать либо int, либо char*, компилятор не может решить, какую перегрузу вы имели в виду.

Самое простое решение - просто придать 0 правильный тип.
Другой вариант - обеспечить перегрузку int, например, путем создания другого шаблона:

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

Ответ 2

Решение очень просто, если мы рассмотрим тип значения константы, который должен быть "unsigned int" вместо "int".

Вместо:

setval(0)

Использование:

setval(0u)

Суффикс "u" сообщает компилятору, что это целое число без знака. Тогда никакого преобразования не потребуется, и вызов будет однозначным.

Ответ 3

замените p.setval(0); на следующее.

const unsigned int param = 0;
p.setval(param);

Таким образом, он точно знает, какой тип имеет константу 0.

Ответ 4

Это неоднозначно, потому что указатель - это просто адрес, поэтому int также можно рассматривать как указатель. 0 (int) может быть легко преобразован в unsigned int или char *.

Короткий ответ - вызвать p.setval() с чем-то однозначно одним из типов, которые он реализовал для: unsigned int или char *. p.setval(0U), p.setval((unsigned int) 0) и p.setval((char *) 0) будут компилироваться.

Как правило, рекомендуется избегать этой ситуации, в первую очередь, не определяя перегруженные функции с подобными типами.

Ответ 5

Используйте

p.setval(static_cast<const char *>(0));

или

p.setval(static_cast<unsigned int>(0));

Как указано ошибкой, тип 0 равен int. Это можно легко отнести к unsigned int или const char *. Сделав бросок вручную, вы сообщаете компилятору, который вы хотите перегрузить.

Ответ 6

Введите значение, чтобы компилятор знал, какую функцию вызывать:

p.setval(static_cast<const char *>( 0 ));

Обратите внимание, что у вас есть ошибка сегментации в вашем коде после его компиляции (в зависимости от того, какую функцию вы действительно хотели вызвать).