func(auto n){
return n * func(n - 1);
};
а вот указать возвращаемый тип как auto нельзя?
auto func(int n){
return n * func(n - 1);
};
А какой бы вы тип тут ожидали?)
Тут бесконечная рекурсия, никакой анализатор не угадает. Умножение int на любой тип может результировать в самые разные типы даже для дефолтных типов, не говоря о переопределенных operator*(int)
int, какой же еще ? В вывод типов здесь и правда усложняется но я думаю что можно в процессе вывода увидеть и заскипать который мы сейчас пытаемся вывести и выводить из остальной части выражения. Возможно в более сложных кейсах компилятору придется решать уравнение ReturnType = ReturnType * int через некий набор базовых уравнений (что операция умножения над типом int * приводит к типу int)
> что операция умножения над типом int * приводит к типу int Это если и слева, и справа инты, а в жизни все сложнее Почему не double, например?
C++ же и так очень быстро компилируется :)
потому что для переменной a и b которые имеют тип int в строчке "auto c = a * b" тип переменной "с" выводится как int
А для переменных a: int и b: double в строчке "auto c = a * b" тип переменной "с" выводится как double
а для переменной a: int, а b: MyWrapper вообще чёрти что может вывестись
Псевдоуравнение ReturnType = ReturnType * int имеет бесконечное множество решение, среди которых есть и int, и double, о чём вообще дальнейший разговор?
Если запретить конверсию (из int в double и в кастомные типы) для текущего еще неизвестного выводимого типа то тогда бесконечного множества решений не будет и вывод типа будет однозначен. Может в каких-то сложных и редких кейсах вывести не получится но в целом вывод возвращаемого типа рекурсивной функци возможен и Flow тому доказательство
Так и запишем в стандарте "будем выводить типы автоматически, решая уравнения, но иногда и с тысячей запретов"
Интересно, где в стандарте Flow написаны правила вывода типов в такой ситуации
flow ничему не доказательство
Вообще, немного странно сравнивать ноунейм фреймворк и стандарт С++. Напихать фич любой дурак может, а поддерживать эти фичи и согласовывать с огромным наследием языка кто будет?
Если я правильно помню в не бесконечной рекурсии вывод будет работать, если выход будет первым обрабатываться, а бесконечная рекурсия без сайд эффектов это все равно ub.
точно, спасибо, теперь если добавить условие то вывод типа работает auto func(auto n){ if(n < 1) return 1; return n * func(n - 1); }; int main(int num) { std::cout << func(11); }
Он не выводит тип. Он просто берет его из return 1; попробуйте переставить местами эти условия - будет CE
ну в целом этого достаточно для большинства кейсов, можно пока не тащить вывод типа через решение системы уравнений)
таким же макаром можно тогда и вручную тип указать :D
Только ваш пример с рекурсией эквивалентен не этому, а другому примеру: auto c = c * b; И соответственно, из c и b мы никак не можем вывести c даже с точки зрения здравого смысла. Этот код абсурден
Обсуждают сегодня