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

Use of 'auto func(int)' before deduction of 'auto' in C++14

本文关键字:auto func int C++14 中的      更新时间:2023-10-16

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

那么,我在这里缺少什么?

这是[dcl.spec.auto/11]:

如果需要具有未支配占位符类型的实体的类型 为了确定表达式的类型,该程序是不形成的。 一旦在函数中看到了未透露的返回语句, 但是,从该语句中得出的返回类型可以在 其余功能,包括其他返回语句。 [示例:

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,这通常是通过在使用点之前移动定义来实现的。如果您实际上不需要使用返回类型扣除额,则可以在使用声明中提供签名(包括返回类型(后使用定义。

clang对此有更好的错误消息:

main.cpp:8:16: error: function 'func' with deduced return type cannot be used before it is defined
    auto ret = func(5);
               ^

我想这是不言自明的。

auto用作不使用尾随返回类型语法的函数声明中的返回类型时,关键字 auto表示返回类型将从其返回的操作数中推导陈述。这意味着在函数func()的定义之前,不能执行扣除,但在此之前已在main()中使用。

您可以在main()之前移动定义,或使用Tailting返回类型语法来指定声明上的返回类型。

在您的示例中,实际上没有理由不能仅在 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;
}

否则您无法使用自动关键字。特别是,您不能在不返回任何内容的递归功能中使用自动。您必须使用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。这实际上只是为了帮助您减少键入,而不是允许"任何类型"的方法。

相关文章: