17

これは 2 つの部分からなる質問です。関数の戻り値を参照に代入しても問題ありませんか? そのような

Foo FuncBar()
{
    return Foo();
}

// some where else
Foo &myFoo = FuncBar();

これでよろしいですか?FuncBar()Foo オブジェクトを返し、現在myFooはそれへの参照であるという私の理解です。

質問の後半。これは最適化ですか?したがって、多くの場合ループで実行する場合は、実行する方がよいでしょう

Foo &myFoo = FuncBar();

また

Foo myFoo = FuncBar();

また、変数の使用を考慮してください。参照を使用すると、より遅い逆参照が必要になりませんか?

4

2 に答える 2

23
Foo &myFoo = FuncBar();

コンパイルされません。そのはず:

const Foo &myFoo = FuncBar();

一時オブジェクト (つまり、FuncBar()右辺値) を返し、非 const への参照にバインドできるのは左辺値だけだからです。

安全ですか?

はい、安全です。

C++ 標準では、一時オブジェクトを const への参照にバインドすると、一時オブジェクトの有効期間が参照自体の有効期間まで長くなるため、一般的なダングリング参照エラーを回避できると規定されています。


Foo myFoo = FuncBar();      

コピーの初期化です。
によって返されたオブジェクトのコピーを作成し、FuncBar()そのコピーを使用して を初期化しmyFooます。myFooステートメントが実行された後は別のオブジェクトです。

const Foo &myFoo = FuncBar();

FuncBar()によって返されたテンポラリを参照にバインドします。これは、返されたテンポラリの単なるエイリアスであり、別のオブジェクトではないことmyFooに注意してください。myFoo

于 2012-10-05T07:05:39.597 に答える
2

参照に「割り当て」ているのではなく、参照にバインドしています。

constこれは、タイプがであり、コンテキストが一時的な有効期間の自動延長がある場合にのみ適切です。

一般に、型Fooではない場合const、例はコンパイルに失敗するはずです。残念ながら、そのコンパイラによって実装される言語拡張により、1 つの一般的なコンパイラでコンパイルされる場合があります。少なくとも 2 つのコンパイラで例 (および通常のコードも!) を試すことをお勧めします。


編集:質問を投稿する前 の調査作業の例として、定義されているものと定義されていないものを少なくとも2つのコンパイラで最高の警告レベルで次の(または非常に類似した)ものをコンパイルする必要がありますCONST

struct Bar {};

#ifdef CONST
    typedef Bar const Foo;
#else
    typedef Bar Foo;
#endif

Foo FuncBar()
{
    return Foo();
}

int main()
{
    // som where else
    Foo &myFoo = FuncBar();
}

まだ行っていない場合は、今すぐ行うことをお勧めします。

于 2012-10-05T07:05:38.940 に答える