1

Когда перегружать функции:Перегрузка функций получает неоднозначные

void add(int a) 
{ 
    a=7; 
    cout<<"int"; 
} 
void add(double a) 
{ 
    a=8.4; 
    cout<<"double"; 
} 
void add(int *b) 
{ 
    *b=4; 
    cout<<"pointer"; 
} 
int main() 
{ 
    char i='a'; //char 
    add(i); 
    return 0; 
} 

ВЫВОД: int

Это работало отлично несмотр на нет функции с типом данных полукокса в качестве параметра.

Но при компиляции кода ниже:

void add(char a) 
{ 
    a='a'; 
    cout<<"int"; 
} 
void add(double a) 
{ 
    a=8.4; 
    cout<<"double"; 
} 
void add(int *b) 
{ 
    *b=4; 
    cout<<"pointer"; 
} 
int main() 
{ 
    int i=4; //int 
    add(i); 
    return 0; 
} 

Дал ошибку (компилятор GCC):

cpp|21|error: call of overloaded 'add(int&)' is ambiguous

Какова логика этого? И как отслеживать контроль прохождения или вывода таких кодов?

+1

http://en.cppreference.com/w/cpp/language/overload_resolution –

+0

Что вы ожидали? –

+0

@ н.м. я ожидал такой же ошибки для выше кода .... – wrangler

ответ

4

Этот пример сводится к различию между Integer Promotion и Integer Conversion. Продвижение, короче:

A prvalue of an integer type other than bool, char16_t, char32_t, or wchar_t whose integer conversion rank (4.13) is less than the rank of int can be converted to a prvalue of type int if int can represent all the values of the source type; otherwise, the source prvalue can be converted to a prvalue of type unsigned int. [...] These conversions are called integral promotions.

, тогда как целое число преобразование является более общим:

A prvalue of an integer type can be converted to a prvalue of another integer type. [...] The conversions allowed as integral promotions are excluded from the set of integral conversions.

Неотъемлемого продвижением является лучше, чем преобразования интегрального преобразования для целей разрешения перегрузки.


В первом примере мы имеем:

add(int); // (1) 
add(double); // (2) 
add(int*); // (3) 

и призывают с char. Только первые два являются жизнеспособными, оба связаны с конверсией. (1) включает в себя Integer Promotion, который имеет рейтинг Promotion. (2) включает в себя плавающее интегральное преобразование, которое имеет ранговое преобразование. Продвижение - это более высокий ранг, чем Конверсия, поэтому (1) однозначно предпочтительнее. enter image description here

Теперь, во втором примере, мы имеем:

add(char); // (1) 
add(double); // (2) 
add(int*); // (3) 

и призывают с int. Еще раз, только первые два являются жизнеспособными, и оба связаны с конверсией. (1) на этот раз включает интегральную конверсию (поскольку char имеет более низкий ранг, чем int), и (2) по-прежнему включает в себя преобразование с плавающим интегралом, оба из которых имеют одинаковый ранг: преобразование.Поскольку у нас есть две конверсии одного ранга, нет «лучшего» преобразования, поэтому нет лучшего жизнеспособного кандидата. Таким образом, мы имеем двусмысленное решение.

+0

Thanx для вашего ответа также вы можете предоставить какие-либо ссылки на ваш ответ. – wrangler

1

Причина, когда нет точного соответствия типа, компилятор ищет ближайшую совпадение. Вот почему, когда это было - char i='a'; ближайший матч был void add(int a)

но когда int i=4; //int есть 2 матча в настоящее время. поэтому он неоднозначен.

+0

что 2 матча? – wrangler

+0

add (int * b) и add (char a) оба из них получают переменную int –

+0

Я так не думаю, что удаление функции с параметром 'double' для кода ниже успешно прошло. – wrangler

1

A char Входит в int без переполнения или потери точности, что объясняет первый код.

Но int не вписывается в char (переполнение), double (отсутствие точности) или int* (несовместимый тип).

+0

Это «неоднозначный», так что это не перегруженный scenerio вместо «подгонки»? –

+0

@zenith, когда я удалил функцию параметра char, он дал результат 'double' для кода ниже, поэтому' int' вписывается в 'double'. – wrangler

+0

@zenith и так же для 'char', когда я удалял double, он дал output' int' (в параметре char), поэтому int также вписывается в 'char i think' – wrangler

Смежные вопросы