Почему следующая программа компилируется
auto factorial(int x) {
if (x <= 1) {
return 1;
} else {
return x * factorial(x - 1);
}
}
int main() {
auto result = factorial(5);
}
, а такая же, но с переставленными условиями, - нет?
auto factorial(int x) {
if (x > 1) {
return x * factorial(x - 1);
} else {
return 1;
}
}
int main() {
auto result = factorial(5);
}
Если функция с дедуцируемым типом возвращаемого значения содержит несколько return, то те return, которые позволяют выполнить дедукцию типа, все должны дедуцировать один и тот же тип.
При этом допускаются return, которые не позволяют дедуцировать тип возвращаемого значения (напр. вызов функции, чей тип возврата еще не дедуцирован, в т.ч. рекурсивный вызов самой себя), но такой return не может быть самым первым в функции (при просмотре сверху-вниз).
То есть самый первый return в функции должен обеспечивать дедукцию типа возвращаемого значения. Остальные return должны либо совпадать с первым по дедуцируемому типу, либо хотя бы не мешать ему (т.е. не дедуцироваться вообще).
Так, смотрим, говорит компилятор... а смотреть он может - вот беда! - только на шаг вперед, не возвращаясь - потому и нельзя использовать функцию, например, без предварительного объявления
auto factorial(int x) {
Ладно, запомним, что тип мы пока не знаем... И поэтому функция пока не объявлена.
if (x > 1) {
return x * factorial(x - 1);
Ой! А что тут вернуть? Если тип factorial мы не знаем? мы сталкиваемся с использованием неизвестной, не объявленной функции :( Что еще можно сделать - только сообщить об ошибке :(
А тут -
auto factorial(int x) {
Ага, запомним, что вы не знаем возвращаемый тип, и пойдем дальше...
if (x <= 1) {
return 1;
Ура! теперь мы знаем, что возвращаемый тип - int! Функция объявлена полностью...
} else {
return x * factorial(x - 1);
так что тут мы вполне можем ее использовать.
Сборка персонального компьютера от Artline: умный выбор для современных пользователей