29 / 1 / 0
Регистрация: 25.02.2020
Сообщений: 82
1

Почему так нельзя делать?(функции с одинаковыми названиями)

03.06.2020, 12:35. Показов 3298. Ответов 11
Метки нет (Все метки)

Author24 — интернет-сервис помощи студентам
Добрый день, форумчане!
Разъясните, пожалуйста, следующее.
Разве мы можем создавать в с++ 2 функции с одинаковыми названиями одного типа?

В нижеприведенном примере есть 2 одноименные функции но с отличными типами данных. аргументы у них тоже разные,и , естественно, вылазит ошибка.
НО, если в аргументах любой из этих функций будут аргументы одного типа, то все работает!!! (например: double Sum(int a, int b).
Как это все работает, почему вылазит ошибка? Ну и судя по всему, нужно объяснить что есть перегрузка функций (на пальцах)))

p.s. это вопрос из теста, делать так, чтобы эта программа заработала не нужно, поправить ее я и сам могу. Помощь нужна именно в понимании как она работает и почему.

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
double Sum(double a, int b)
{
    cout << "Sum(double, int) ";
    return a + b;
}
 
int Sum(int a, double b)
{
    cout << "Sum(int, double) ";
    return a + b;
}
void main()
{
    cout << Sum(12, 5);
}
0
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
03.06.2020, 12:35
Ответы с готовыми решениями:

Объясните, почему так нельзя делать?
using namespace std; uint32_t foo(uint32_t c, uint32_t a, const vector&lt; uint32_t&gt; &amp; data) { ...

Почему нельзя так делать? Конструктор перемещения?
У меня возникла проблема с хранением объектов класса в векторе векторов, объявленном в другом...

Ошибка в классе или так делать нельзя?
#include &lt;iostream&gt; using namespace std; class student { public: virtual void vvod (int a...

FindComponent. Почему так нельзя?
Добрый вечер. В зависимости от переменной ind мне надо выбрать ADOQuery1 или ADOQuery2. Что я...

11
18822 / 9826 / 2401
Регистрация: 30.01.2014
Сообщений: 17,260
03.06.2020, 12:40 2
m054, ошибка из-за неоднозначности преобразования.

Вы передаете два int.
На выбор есть два варианта: double, int и int, double.
Эти два варианта равноценны с точки зрения необходимых преобразований аргументов,
Sum(12 int -> double, 5 int -> int)
или
Sum(12 int -> int, 5 int -> double)
поэтому возникает ошибка.

Добавлено через 1 минуту
Цитата Сообщение от m054 Посмотреть сообщение
Разве мы можем создавать в с++ 2 функции с одинаковыми названиями одного типа?
Одного - нет. Но у вас типы разные же.
2
Диссидент
Эксперт C
27706 / 17322 / 3812
Регистрация: 24.12.2010
Сообщений: 38,979
03.06.2020, 12:45 3
m054, 12 и 5 - имеют тип int. Фунуции Sum(int, int) нет. Компилятор пытается привести аргументы так, чтоб функция таки была. Но это можно сделать двумя способыми
Sum((double)12, 5)
Sum(12, (double)5)
Вот компилятор и мычит, как Буриданов осел.

Добавлено через 2 минуты
Практически, я другими словами подтвердил соображения уважаемого DrOffset,
1
18822 / 9826 / 2401
Регистрация: 30.01.2014
Сообщений: 17,260
03.06.2020, 12:49 4
Цитата Сообщение от m054 Посмотреть сообщение
В нижеприведенном примере есть 2 одноименные функции но с отличными типами данных
Если что, тип функции - это не то, что она возвращает, а все вместе, с типами параметров.

Например тип вот этой функции
C++
1
double Sum(double a, int b)
Вот такой:
C++
1
double(double, int)
перегрузка осуществляется по типам параметров. возвращаемый тип в расчет не берется.
вы можете сделать сколько угодно одноименных функций, для перегрузки достаточно, чтобы все они отличались типами и\или порядком параметров.
1
Эксперт С++
8739 / 4317 / 960
Регистрация: 15.11.2014
Сообщений: 9,760
03.06.2020, 13:28 5
у тебя есть две функции:
Цитата Сообщение от m054 Посмотреть сообщение
double Sum(double a, int b)
Цитата Сообщение от m054 Посмотреть сообщение
int Sum(int a, double b)
первая принимает яблоки и груши.
вторая принимает груши и яблоки.

ты пытаешься вызвать функцию, указав на входе только яблоки (или только груши)
Цитата Сообщение от m054 Посмотреть сообщение
cout << Sum(12, 5);
и вот какая версия, по твоему, должна быть запущена?
1
29 / 1 / 0
Регистрация: 25.02.2020
Сообщений: 82
04.06.2020, 09:50  [ТС] 6
ок, с этим разобрался. Всем +1 спасибо))
теперь вот это:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
int sum(int a, int b)
{
    cout << "sum(int, int) ";
    return a + b;
}
 
int sum(int a, int b, int c = 10)
{
    cout << "sum(int, int, int) ";
    return a + b + c;
}
 
void main()
{
    cout << sum(10, 12);
}
Почему я не могу воспользоваться именно 1й функцией? Почему именно 2-й должен пользоваться?
0
Диссидент
Эксперт C
27706 / 17322 / 3812
Регистрация: 24.12.2010
Сообщений: 38,979
04.06.2020, 09:58 7
Цитата Сообщение от m054 Посмотреть сообщение
теперь вот это:
Опять же, многозначность выбора. Почему компилятор выбирает именно вторую? И не ругается? А Бог его знает!
Но лучше такого выбора компилятору не давать.
1
Вездепух
Эксперт CЭксперт С++
11689 / 6368 / 1723
Регистрация: 18.10.2014
Сообщений: 16,051
04.06.2020, 10:31 8
Цитата Сообщение от m054 Посмотреть сообщение
Почему я не могу воспользоваться именно 1й функцией? Почему именно 2-й должен пользоваться?
Что за странный вопрос? Конечно вы можете воспользоватся первой функцией. Но откуда компилятору знать, что вы хотите воспользоваться именно первой? В вашем коде на это нет никакого намека.

Из вызова sum(10, 12) совсем не следует, что вы хотите воспользоваться именно первой. Из этого вызова вообще ничего не понятно. В той ситуации, которую вы создали своей перегрузкой функций, выбрать первую функцию можно только явно, вручную и только довольно неэлегантным способом

C++
1
2
int (*s)(int, int) = sum;
std::cout << s(10, 12) << std::endl;
или в одну строку

C++
1
std::cout << ((int (*)(int, int)) sum)(10, 12)  << std::endl; // это `static_cast`
Цитата Сообщение от m054 Посмотреть сообщение
void main()
Что такое void main()? int main(), а не void main().
1
76 / 68 / 10
Регистрация: 11.07.2016
Сообщений: 320
04.06.2020, 10:34 9
m054, обнови компилятор лучше. Любой серьёзный современный должен остановиться с ошибкой, в которой прямо и скажет, почему так делать нельзя.
0
Вездепух
Эксперт CЭксперт С++
11689 / 6368 / 1723
Регистрация: 18.10.2014
Сообщений: 16,051
04.06.2020, 10:54 10
Цитата Сообщение от m054 Посмотреть сообщение
Помощь нужна именно в понимании как она работает и почему.
...И мораль той басни такова, что при написании перегруженных функций вам следует заботиться о том, чтобы в последующем по типовому набору аргументов в вашем коде компилятор мог сам однозначно определить, какую функцию вы хотите вызвать. Разве что в небольшой доле случаев можно допустить, что вызывающему коду придется немножко помочь компилятору разрешить неоднозначность.

А то, что написано в ваших примерах - это как раз пример того, как не нужно делать. Ибо в ваших вариантах неоднозначности будут происходить почти всегда.
0
Эксперт С++
8739 / 4317 / 960
Регистрация: 15.11.2014
Сообщений: 9,760
04.06.2020, 15:23 11
Цитата Сообщение от m054 Посмотреть сообщение
Почему я не могу воспользоваться именно 1й функцией? Почему именно 2-й должен пользоваться?
ни почему.
твой код не компилируется:

Код
source_file.cpp(18): error C2668: 'sum': ambiguous call to overloaded function
source_file.cpp(10): note: could be 'int sum(int,int,int)'
source_file.cpp(4): note: or       'int sum(int,int)'
source_file.cpp(18): note: while trying to match the argument list '(int, int)'
опять таки:
с чего ты взял что должен запуститься именно первый вариант?
1
29 / 1 / 0
Регистрация: 25.02.2020
Сообщений: 82
10.06.2020, 12:10  [ТС] 12
Цитата Сообщение от hoggy Посмотреть сообщение
Сообщение от m054
Почему я не могу воспользоваться именно 1й функцией? Почему именно 2-й должен пользоваться?
ни почему.
твой код не компилируется:
КодВыделить код
source_file.cpp(18): error C2668: 'sum': ambiguous call to overloaded function
source_file.cpp(10): note: could be 'int sum(int,int,int)'
source_file.cpp(4): note: or 'int sum(int,int)'
source_file.cpp(18): note: while trying to match the argument list '(int, int)'
опять таки:
с чего ты взял что должен запуститься именно первый вариант?
уфф)))
это задачка из теста, не факт что она вообще должна компилироваться.
Собственно вопросов по этому коду больше нет. Спасибо всем участвующим.
0
10.06.2020, 12:10
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
10.06.2020, 12:10
Помогаю со студенческими работами здесь

Почему нельзя сделать так?
И как правильно сделать то, что я хочу сделать?) int num = 7; char ch =...

Почему предел нельзя определить так
Здравствуйте. Почему подобный предел нельзя определить вот так? Вроде же выглядит вполне...

Сравнение файлов с одинаковыми названиями
Дано два каталога(dir1, dir2), содержащих файлы *.txt и не содержащие подкаталогов. Наполнить...

Почему два char нельзя сравнивать так ==?
Почему два char нельзя сравнивать так ==?

Почему нельзя так объявить двумерный массив?
Ошибка возникает если для массива tempArray при объявлении(и одновременной инициализации)...

Как сделать так, чтобы нельзя было ничего делать с главным фреймом, пока открыт диалог?
Доброго дня. Я новичок в программировании. Пишу крестики-нолики. Допустим, игрок выигрывает,...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
12
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2024, CyberForum.ru