web-dev-qa-db-ja.com

C ++ 14で「auto」を差し引く前の「auto func(int)」の使用

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);

だから、私はここで何が欠けていますか?

24
msc

これは [dcl.spec.auto/11]

式のタイプを判別するために、推定されないプレースホルダータイプを持つエンティティのタイプが必要な場合、プログラムの形式は正しくありません。ただし、破棄されていないreturnステートメントが関数で見つかると、そのステートメントから推定される戻り値の型は、他の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の場合、これは通常、使用ポイントの前に定義を移動することで実現されます。実際に戻り型の推論を使用する必要がない場合、宣言で戻り型を含む署名を提供すると、使用後も定義を保持できます。

34
Griwes

Clangには、そのためのより良いエラーメッセージがあります。

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

それは一目瞭然だと思います。

27

末尾の戻り型構文を使用しない関数宣言でautoが戻り型として使用される場合、キーワードautoは、戻り型がreturnステートメントのオペランドから推定されることを示します。つまり、関数func()の定義まで演deを実行することはできませんが、それまではmain()で使用されていました。

定義をmain()の前に移動するか、末尾の戻り型構文を使用して宣言の戻り型を指定できます。

5
songyuanyao