我使用 this.client = new MobileServiceClient(Constants.ApplicationURL);
this.categoryTable = client.GetTable<Category>();
IEnumerable<Category> categories = await categoryTable.ToEnumerableAsync();
在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; }
那么,我在这里错过了什么?
答案 0 :(得分:32)
如果需要具有未减少占位符类型的实体的类型 为了确定表达式的类型,程序是不正确的。 一旦在函数中看到非丢弃的return语句, 但是,可以使用从该语句推导出的返回类型 函数的其余部分,包括其他返回语句。 [实施例:
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 }
- 结束示例]
要将其翻译成英文:编译器需要先知道返回类型才能使用该函数。如果像这样使用auto
,通常可以通过在使用点之前移动定义来实现。如果您实际上不需要使用退货类型扣除,那么如果您在声明中提供签名(包括退货类型),则可以在使用后保留定义。
答案 1 :(得分:27)
Clang有一个更好的错误信息:
main.cpp:8:16: error: function 'func' with deduced return type cannot be used before it is defined
auto ret = func(5);
^
我想这是不言自明的。
答案 2 :(得分:5)
当auto
用作不使用尾随返回类型语法的函数声明中的返回类型时,关键字auto
表示将从其返回的操作数推导出返回类型声明。这意味着在函数func()
的定义之前不能执行演绎,但在此之前它已在main()
中使用。
您可以在main()
之前移动定义,或使用尾随返回类型语法指定声明上的返回类型。
答案 3 :(得分:0)
在您的示例中,确实没有理由不能仅将函数的实现移到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关键字。特别是,您不能在不返回任何内容的递归函数中使用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)
{
...
如果您确实想要一个支持各种返回类型的函数,则无论如何都想使用模板,而不要使用auto
。这确实只是在帮助您减少打字,而仅仅是允许“任何类型”的方式。