Почему перегрузка вызывает неоднозначный вызов, если используется unsigned? - PullRequest
1 голос
/ 17 июля 2011
void foo(int,int) {}
void foo(int ,float) {}
void foo(float,int) {}

void main()
{
  unsigned int i = 10;
  unsigned float f = 1.0;       //line 5
  foo(i,f); // ambiguous call error
}

замена строки 5 на

float f = 1.0;

заставляет программу работать. Почему это так?

Я работаю над Visual Studio 2005.

Ответы [ 4 ]

5 голосов
/ 17 июля 2011

Нет такого типа данных, как unsigned float. Обратите внимание на предупреждения компилятора; если вы не получаете никакого повышения уровня предупреждения. При запуске этого примера в Visual Studio 2010 похоже, что компилятор игнорирует ключевое слово float в объявлении

unsigned float f = 1.0;

Это делает f unsigned int. Поскольку у вас нет перегрузки foo(), которая принимает int и unsigned int, компилятор не может определить, какую перегрузку вызвать. Если вы добавите еще одну перегрузку

void foo(int,unsigned int) {}

ошибка неоднозначного вызова исчезает.

3 голосов
/ 17 июля 2011

Преобразование из unsigned int в int или float приводит к потере точности, и оба компилятора считают их равными. Вы должны добавить явный случай, чтобы компилятор решал, какой использовать, например ::10000

foo(i, static_cast<float>(f));

Обратите внимание, что нет такой вещи как unsigned float. Если компилятор принимает это, он не соответствует стандартам (VC2010 предупреждает об этом, не уверен насчет VC2005).

<Ч />

Соответствующими разделами стандарта C ++ 98 являются раздел 4, в котором числовой тип ранжируется как точное совпадение, повышение или преобразование, и раздел 13.3.3.2, в котором определяется, как ранжируются неявные преобразования. разрешение перегрузки. В последнем разделе в подпункте 4 говорится:

Стандартные последовательности преобразования упорядочены по их рангу: точное совпадение - это лучшее преобразование, чем повышение, что лучше, чем преобразование.

Преобразование из unsigned int в float или int в любом случае оценивается как «Преобразование», поэтому оно «неразличимо», что делает перегрузку неоднозначной.

Поскольку unsigned float не является действительным типом в соответствии со стандартом, трудно сказать, как это применимо в вашей ситуации, но ваш компилятор, по-видимому, рассматривает преобразование из unsigned float в float или int как неразличимое. тоже.

0 голосов
/ 17 июля 2011

Какой тип unsigned float ??Ничего из того, о чем я когда-либо слышал.Проверьте this .

Насколько я понимаю, типы с плавающей запятой (т.е. float, double и т. Д.) Всегда подписаны.

РЕДАКТИРОВАТЬ: Это не будетскомпилировать в ideone (это gcc 4.3.4) (выдает ошибку «недопустимый знак / неподписанный с плавающей точкой»):

int main()
{
    unsigned float ff = 1.0;

    return ff;
}

Я не знаю, что делает MSVC, если принимает unsigned float.Я не думаю, что это допустимый тип.

0 голосов
/ 17 июля 2011

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

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