2

Sun Studio 12.1 のタイトルから、次のスニペットで警告が表示されます。

#include <vector>

std::vector<int> g()
{
  std::vector<int> result;
  result.push_back(5);
  return result;
}

int main()
{
  int b = g()[0];  // <- Warning in this line

  return b;
}

警告テキストは次のとおりです。

Warning: should not initialize a non-const reference with a temporary.

const 以外の参照を一時的に初期化するのは悪いことだとわかっていますが、ここでそれがどのように行われるのかわかりません。それ自体が一時的なベクトルの最初の要素への参照を返すことは知ってい[0]ますが、問題が何であるかはわかりません。

誰か説明してくれませんか

  • コンパイラに文句を言うのはなぜですか?
  • それは正当な警告ですか?
    • はいの場合、何を変更する必要がありますか?
    • いいえの場合、どうすればエレガントに沈黙させることができますか?
4

3 に答える 3

4

いいえ、合法ではありません。の戻り値g()は一時的ですが、const ではありません。非 const 参照取得することはできません。非 const メンバーoperator[]はここで呼び出すのに完全に有効であり、double から integer への変換も同様に安全です。

于 2011-04-19T12:09:45.933 に答える
2

この Sun コンパイラは非常に奇妙に見えます。私にはまったく正当なものとは思えません。Ideoneは問題なくコンパイルできます。

消音部分について:

std::vector<double> const tmp = g();
int b = tmp[0];

つまり、一時的な浮動状態のままにする代わりに、名前付き変数を導入します。

編集:

コメントで示唆されているように、戻り値を const 修飾すると役立つ場合があります。

std::vector<double> const g();

int main() {
  int b = g()[0];
  return b;
}
于 2011-04-19T12:15:28.277 に答える
1

はい、非 const 参照を一時的に初期化します。ただし、過負荷の解決中に概念的にのみであり、実際にはそうではありません。コンパイラはそれについて警告しません。

オーバーロードの解決では、operator[]この関数パラメーター シグネチャがあります。

operator[](std::vector<int>&, std::vector<int>::size_type);

最初のパラメーターはによって返される一時を受け取りますが、g()前述のように、それは問題なく、C++ はその参照に対して特に例外を作成します。これは、いわゆる「暗黙のオブジェクトパラメーター」であり、オーバーロードの解決が一時的な引数を受け入れるようにします。

于 2011-04-19T18:46:51.873 に答える