web-dev-qa-db-ja.com

関数のパラメーターリストで初期化された変数のスコープ

次のコードは、問題なく見えるようにビルド、コンパイル、実行(C++、mingw)します。ただし、関数のパラメーターリスト内の初期化子リストで作成されたオブジェクトが、関数が参照によって引数を受け取ったとしても、その関数のスコープを通過することを保証しますか?

そうでない場合、関数のパラメーターリスト(参照によって引数をとります)の初期化リストを使用してオブジェクトを作成すると、すぐに破壊されるため危険である可能性があります。この場合、関数にはコピーしますが、別のプロセスによって再割り当てされる場合とそうでない場合があるメモリへの参照?

struct S
{
  S() : a(0), b(0) {}
  S(int a, int b) : a(a), b(b) {}
  int a;
  int b;
};

void foo(const S& s)
{
  std::cout << "s.a = " << s.a << std::endl;
  std::cout << "s.b = " << s.b << std::endl;
}

int main()
{
  foo({4,5}); // <-- What is the scope of the struct initialized here?

  return 0;
}
28
magnus

cppreference [lifetime] によると:

すべての一時オブジェクトは破棄されます。これは、それらが(字句的に)作成されたポイントを含む完全式を評価する最後のステップとして、複数の一時オブジェクトの場合作成された場合、作成された順序とは逆の順序で破棄されます。これは、その評価が例外のスローで終了した場合でも当てはまります。

つまり、一時オブジェクトは破棄されますafter関数が返されたので、完全に安全です。

34
amc176

ここでは、prvalueが具体化され、braced-init-list _{4,5}_からタイプSの一時オブジェクトを作成します。これは、完全式の最後で破棄されます。あなたの場合はfoo({4,5});です。

7
Yola