在 C++14 中推导 'auto' 之前使用 'auto func(int)'
Use of 'auto func(int)' before deduction of 'auto' in C++14
我使用 C++14
在 GCC 中编译了以下程序。
#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);
那么,我在这里缺少什么?
Clang 有一个更好的错误消息:
main.cpp:8:16: error: function 'func' with deduced return type cannot be used before it is defined
auto ret = func(5);
^
我想这是不言自明的。
当 auto
在不使用尾随 return 类型语法的函数声明中用作 return 类型时,关键字 auto
表示 return 类型将从其 return 语句的操作数中推导出来。也就是说在函数func()
的定义之前不能进行推导,但在此之前它已经在main()
.
中使用过
您可以将定义移到 main()
之前,或使用尾随 return 类型语法在声明中指定 return 类型。
If the type of an entity with an undeduced placeholder type is needed
to determine the type of an expression, the program is ill-formed.
Once a non-discarded return statement has been seen in a function,
however, the return type deduced from that statement can be used in
the rest of the function, including in other return statements.
[ Example:
auto n = n; // error, n's type is unknown
auto f();
void g() { &f; } // error, f's return type is unknown
auto sum(int i) {
if (i == 1)
return i; // sum's return type is int
else
return sum(i-1)+i; // OK, sum's return type has been deduced
}
— end example ]
将其翻译成英文:编译器需要知道 return 类型才能使用该函数。如果 auto
像这样使用,这通常是通过将定义移到使用点之前来实现的。如果您实际上不需要使用 return 类型推导,如果您在声明中提供签名,包括 return 类型,则可以保留使用后的定义。
在你的例子中,你真的没有理由不能在 main()
:
之前移动函数的实现
#include <iostream>
using namespace std; // you should avoid this, too
auto func(int i)
{
if (i == 1)
return i;
else
return func(i-1) + i;
}
int main()
{
auto ret = func(5);
return 0;
}
否则你就不能使用auto关键字。特别是,您不能在没有 return 任何东西的递归函数中使用 auto 。你必须使用 void
。这适用于 lambda 函数。例如:
int main()
{
auto f = [](int i)
{
// ... do something with `i` ...
if(i > 0)
{
f(i - 1); // <-- same error here
}
}
auto ret(func(5));
return 0;
}
调用f(i - 1)
有问题。要修复它,您必须将 auto
替换为实际类型:
int main()
{
typedef std::function<void(int)> func_t;
func_t f = [](int i)
{
...
如果您真的想要一个支持不同 return 类型的函数,您无论如何都想使用模板,而不是 auto
。这实际上只是为了帮助您减少打字,而不是允许 "any type".
我使用 C++14
在 GCC 中编译了以下程序。
#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);
那么,我在这里缺少什么?
Clang 有一个更好的错误消息:
main.cpp:8:16: error: function 'func' with deduced return type cannot be used before it is defined
auto ret = func(5);
^
我想这是不言自明的。
当 auto
在不使用尾随 return 类型语法的函数声明中用作 return 类型时,关键字 auto
表示 return 类型将从其 return 语句的操作数中推导出来。也就是说在函数func()
的定义之前不能进行推导,但在此之前它已经在main()
.
您可以将定义移到 main()
之前,或使用尾随 return 类型语法在声明中指定 return 类型。
If the type of an entity with an undeduced placeholder type is needed to determine the type of an expression, the program is ill-formed. Once a non-discarded return statement has been seen in a function, however, the return type deduced from that statement can be used in the rest of the function, including in other return statements. [ Example:
auto n = n; // error, n's type is unknown auto f(); void g() { &f; } // error, f's return type is unknown auto sum(int i) { if (i == 1) return i; // sum's return type is int else return sum(i-1)+i; // OK, sum's return type has been deduced }
— end example ]
将其翻译成英文:编译器需要知道 return 类型才能使用该函数。如果 auto
像这样使用,这通常是通过将定义移到使用点之前来实现的。如果您实际上不需要使用 return 类型推导,如果您在声明中提供签名,包括 return 类型,则可以保留使用后的定义。
在你的例子中,你真的没有理由不能在 main()
:
#include <iostream>
using namespace std; // you should avoid this, too
auto func(int i)
{
if (i == 1)
return i;
else
return func(i-1) + i;
}
int main()
{
auto ret = func(5);
return 0;
}
否则你就不能使用auto关键字。特别是,您不能在没有 return 任何东西的递归函数中使用 auto 。你必须使用 void
。这适用于 lambda 函数。例如:
int main()
{
auto f = [](int i)
{
// ... do something with `i` ...
if(i > 0)
{
f(i - 1); // <-- same error here
}
}
auto ret(func(5));
return 0;
}
调用f(i - 1)
有问题。要修复它,您必须将 auto
替换为实际类型:
int main()
{
typedef std::function<void(int)> func_t;
func_t f = [](int i)
{
...
如果您真的想要一个支持不同 return 类型的函数,您无论如何都想使用模板,而不是 auto
。这实际上只是为了帮助您减少打字,而不是允许 "any type".