Вызов перегруженной функции неоднозначен - PullRequest
21 голосов
/ 12 января 2011

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

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

Ответы [ 6 ]

21 голосов
/ 12 января 2011

Литерал 0 имеет два значения в C ++.
С одной стороны, это целое число со значением 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*);
};
13 голосов
/ 28 ноября 2011

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

Вместо:

setval(0)

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

setval(0u)

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

3 голосов
/ 12 января 2011

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

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

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

1 голос
/ 12 января 2011

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

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

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

1 голос
/ 12 января 2011

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

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

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

1 голос
/ 12 января 2011

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

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

или

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

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...