Использование "auto func (int)" перед выводом "auto" в С++ 14
Я скомпилировал следующую программу в GCC с помощью C++14
.
#include <iostream>
using namespace std;
auto func(int i);
int main()
{
auto ret = func(5);
return 0;
}
auto func(int i)
{
if (i == 1)
return i;
else
return func(i-1) + i;
}
Но я получаю следующую ошибку.
In function 'int main()': 8:16: error: use of 'auto func(int)' before
deduction of 'auto'
auto ret = func(5);
Итак, что мне здесь не хватает?
Ответы
Ответ 1
Это [dcl.spec.auto/10]:
Если требуется тип объекта с неподтвержденным типом-заполнителем для определения типа выражения программа плохо сформирована. После того, как в функции была обнаружена неотключенная операция возврата, однако возвращаемый тип, выведенный из этого утверждения, может быть использован в остальная часть функции, в том числе в других операторах return. [Пример:
auto n = n; // error, n type is unknown
auto f();
void g() { &f; } // error, f return type is unknown
auto sum(int i) {
if (i == 1)
return i; // sum return type is int
else
return sum(i-1)+i; // OK, sum return type has been deduced
}
- конец примера]
Чтобы перевести это на английский язык: компилятор должен знать тип возвращаемого значения, прежде чем вы сможете использовать эту функцию. В случае auto
, используемого как это, это обычно достигается путем перемещения определения до точки использования. Если вам действительно не нужно использовать вычет типа возвращаемого типа, вы можете сохранить определение после использования, если в декларации вы указали подпись, включая тип возврата.
Ответ 2
У Clang есть гораздо лучшее сообщение об ошибке для этого:
main.cpp:8:16: error: function 'func' with deduced return type cannot be used before it is defined
auto ret = func(5);
^
Я думаю, что самоочевидно.
Ответ 3
Когда auto
используется как тип возвращаемого значения в объявлении функции, который не использует синтаксис типа возвращаемого типа, ключевое слово auto
указывает, что тип возвращаемого значения будет выведен из операнда его оператора return. Это означает, что вывод не может быть выполнен до определения функции func()
, но до этого он использовался в main()
.
Вы можете перенести определение до main()
или использовать синтаксис типа возвращаемого типа для указания типа возврата в объявлении.