2

次の例を検討してください。

#include <iostream>
#include <string>

struct foo { std::string value; };
inline foo bar() { return { "42" }; }

std::string my_func() {
    auto &x = bar();
    ^^^^^^^^^^^^^^^^
    return x.value;
}

int main() {
  std::cout << my_func() << std::endl;  
}

GCCCLANGの両方をコンパイルすると、おそらく当然のことながら、同じエラーが発生します。

エラー: タイプ 'foo' の右辺値からのタイプ 'foo&' の非 const 参照の無効な初期化

しかし、驚いたことに、VC++2015 では問題なくコンパイルおよび実行されます。

  • これは VC++2015 のバグですか?
  • ステートメントがプログラムを不適切な形式にする場合、標準はオブジェクトにauto暗黙的に追加できると規定していますか?const
4

3 に答える 3

1

これは VC++2015 のバグですか?

レドモンドの被告はしばしばそれを「機能」と呼んでいますが、それはコンパイラの混乱の中では完全にばかげたバグです (で修正可能/Za)。その理由を見てみましょう...

auto &x = bar();

よし、それであなたは電話bar()しているのですね?これによりrvalue、つまりアドレスのないオブジェクトが生成されます。lvalue現在、 (アドレスを取得できるオブジェクト) 参照 (aka: &) を にバインドすることはできませんrvalue。これまでのところ、それがあなたのコードが違法である理由です。

ただし、C++ 言語には、const lvalue参照を にバインドできるようにする特別なルールがありrvalue、有効期間を効果的に延長します。したがって、これは有効なコードになります...

const auto &x = foo();

編集:ところで...

標準は、ステートメントがプログラムを不適切な形式でレンダリングするときに、 auto がオブジェクトに暗黙的に constness を追加できると規定していますか?

非標準的な用語/平易な英語で言えば、T&が拒否された場合、 も拒否されますauto&。CV 修飾子 (constおよびvolatile) は、 から自動的に推定されませんauto

これがあなたに光をもたらしたことを願っています!

于 2015-11-05T22:23:39.477 に答える