16

以前に Q&A がありました: C++ での宣言のポイント。ルール宣言ポイントは、多くの状況にうまく適用できます。autoさて、このルールの組み合わせでの使用について混乱しました。

次の 2 つのコードを検討してください。

私。x単独で宣言する(動作するとは思わない) :

{
  auto x = x;
}

ii. 内側xを外側x で宣言する (gcc 4.8.x ではエラーになります) :

{
  int x = 101; // the outer x
  {
    auto x = x; // the inner x
  }
}

宣言点の規則によれば、機能するはずですが、機能しません。標準には、私が見逃した別のルールがあるようです。問題は、使用時の宣言ポイントはどこautoですか?

 

次の 2 つの可能性があります。

私。宣言のポイントが の後=、ステートメントの最後にある場合:

auto object = expression;
                        ^
                        Is it here? If it is, why gcc complains?

したがって、2 番目の宣言は有効であり、機能する必要がありxます。これは、その外側の宣言 (前に宣言されている) しかないためです。したがってauto x=x、 は有効であり、内部xは に割り当てられる必要があります101

 

ii. 宣言のポイントが前にある場合=:

auto object = expression;
           ^

autoまあ、次の式を見るまで待たなければならないので意味がありません。たとえばauto x;無効です。


更新:宣言のルールポイントで説明する回答が必要です。

4

4 に答える 4

19
auto x = x; // inner x

は不正です。

C++ 11標準から引用するには(強調鉱山):

7.1.6.4 自動指定子

...

3それ以外の場合、変数の型は初期化子から推定されます。宣言されている変数の名前は、初期化式には現れません。...

そのため、(リンクした質問で説明されているように) xafterがinに=解決されるため、上記のコードは形式が正しくありません。xauto x

于 2013-10-02T09:22:39.730 に答える
10

他の種類の定義と同様にx、初期化子 for の右側にあるauto x = xは local に解決されauto xます。C++ は常にこれを行ってきました (つまりint x = x、コンパイルしますが、未定義の動作が発生します)。

auto x = xwhile がスコープ内にあるため、コンパイルに失敗する理由xは、既知の型がまだないためです。式から型を推定できないため、初期化子として使用すると失敗します。

他の種類の宣言と同様xに、宣言子である の後にスコープ内にありauto xます。

int x = 10;
int y = 20;
{
    int x = x;  // This is NOT the outer x. This is undefined behaviour (reading an
                // uninitialised variable).
    auto y = y; // This is NOT the outer y. This is a compile error because the type of
                // y is not known.
}
于 2013-10-02T09:15:17.320 に答える
5

より明示的な診断を含む例を追加するだけです:

auto ll = [&] { ll(); };

結果 (gcc):

error: variable ‘auto ll’ with ‘auto’ type used in its own initializer

または(clang):

error: variable 'll' declared with 'auto' type cannot appear in its own initializer
    auto ll = [&] { ll(); };
                    ^

これには明確なルールがあることがわかります。スペックは見ていません。

于 2013-10-02T09:23:37.093 に答える
1

コンパイラはステートメント全体 (行の先頭から次のセミコロンまで) を読み取り、演算の優先度を使用してステートメントのさまざまな部分を評価しますauto x。番目の=サインが取られた後に出てきたタイプ。

例えば:

template <typename T>
T sum(T a, T b)
{
    return a+b;
}

int main()
{
    auto x = sum<double>(1,5); // x here is a double, because the return value is double
    auto y = sum<int>(1,7); //y is an int, because the return value is int
}

あなたauto x = xの については、同じ変数名を再定義しています。それは無効です!auto y = x動作します。

于 2013-10-02T09:15:35.320 に答える