Компилятор был сбит с толку, когда вы вызывали volume(double, double, int)
, так как компилятор должен преобразовывать двойные числа в целые числа и вызывать volume(int, int, int)
или должен преобразовывать целые числа в двойные числа и вызывать volume(double, double, double)
.
Для продвинутых читателей
Как работает перегрузка?
Есть 3 шага к разрешению перегрузки.
Поиск функций-кандидатов : Функции с тем же именем, что и у вызываемой функции, называются функциями-кандидатами. В вашем случае все функции с именем volume
являются функциями-кандидатами, потому что вы вызвали volume(..)
Поиск жизнеспособных функций. Чтобы быть жизнеспособной, функция должна пройти два теста. Во-первых, функция должна иметь столько же параметров, сколько аргументов в вызове. (кроме аргументов по умолчанию). Во-вторых, каждый аргумент должен соответствовать типу соответствующих параметров или быть конвертируемым в него. В вашем случае volume(int,int,int) and volume(double, double, double)
являются жизнеспособными функциями.
Поиск наилучшего соответствия, если таковое имеется. На последнем этапе разрешения перегрузки определяются жизнеспособные функции, которые лучше всего соответствуют аргументам. Лучшее здесь означает -- точное совпадение типов лучше, чем совпадение, требующее преобразования типа аргумента в тип параметра. В вашем случае лучшего совпадения нет. Ваш вызов volume(double, double, int)
не соответствует ни одной жизнеспособной функции.
Проблема с несколькими параметрами
Давайте рассмотрим этот пример более простого случая
void foo(int x, int y);
void foo(double x, double y);
Предположим, мы делаем вызов как
foo(4.2, 5) //double and int
Вышеупомянутые два foo являются функциями-кандидатами (то же имя).
И обе они также являются жизнеспособными функциями, потому что вызов может быть сделан путем преобразования, и оба принимают 2 аргумента.
Так что теперь компилятор решает аргумент за аргументом, какая функция лучше всего подходит.
Есть совпадение, если существует только и только одна функция, для которой:
1. Соответствие для каждого аргумента не хуже, чем соответствие, требуемое любой другой жизнеспособной функцией
2. Существует по крайней мере один аргумент, для которого соответствие лучше, чем соответствие, предоставляемое любой другой жизнеспособной функцией
Таким образом, когда компилятор проверяет первый аргумент по первому параметру жизнеспособной функции, он выбирает, что foo(double, double)
является лучшим соответствием, но когда он проверяет второй аргумент, он обнаруживает, что foo(int, int)
является лучшим соответствием.
Поэтому вызов неоднозначен. Каждой жизнеспособной функции лучше соответствовать по одному из аргументов вызова.
Решение
Чтобы устранить такую двусмысленность, вам нужно убедиться, что компилятор может найти наилучшие совпадения. Поэтому вам нужно явно преобразовать аргументы. В вашем случае вы можете либо преобразовать двойные числа в целые, либо последнее целое в двойное. Этот вызов не будет двусмысленным:
volume(2.0, 9.7, static_cast<double>(3));
Почему static_cast
?? Ну, в общем, вы можете напрямую написать 3.0, и он будет работать нормально, но вы не можете сделать это с некоторыми переменными, скажем
int x = 10;
float a= 2.1, b=4.8;
for(int t=1;t<=x;t++){
volume(a,b,static_cast<double>(t));
//do something with t here
}
ПРИМЕЧАНИЕ
Вы не должны пытаться явно преобразовывать аргументы в вызове функции для перегрузки в целом. Скорее вы должны создать новую перегруженную функцию с тем, что вы пытаетесь сделать. Но я надеюсь, что вы делаете это только для обучения, все в порядке. В проектах вы должны избегать этих явных преобразований.
person
coder3101
schedule
21.07.2018