使用' auto func(int)'在扣除' auto'之前在C ++中14

时间:2017-04-20 08:51:37

标签: c++ function gcc c++14 auto

我使用 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;  
}

那么,我在这里错过了什么?

4 个答案:

答案 0 :(得分:32)

这是[dcl.spec.auto/10]

  

如果需要具有未减少占位符类型的实体的类型   为了确定表达式的类型,程序是不正确的。   一旦在函数中看到非丢弃的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。这确实只是在帮助您减少打字,而仅仅是允许“任何类型”的方式。