1

皆さん、こんにちは!

自分のコードを調べてみると、次の興味深い行にたどり着きました。

const CString &refStr = ( CheckCondition() ) ? _T("foo") : _T("bar");

今、私は完全に途方に暮れており、なぜそれが合法なのか理解できません. 私が理解している限り、const 参照は右辺値または左辺値のいずれかで初期化する必要があります。初期化されていない参照は存在できません。しかし ()?演算子は、参照に値を割り当てる前に CheckCondition() 関数を実行します。CheckCondition() が実行されている間、refStr は存在しますが、まだ初期化されていないことがわかります。CheckCondition() が例外をスローしたり、goto ステートメントで制御を渡したりするとどうなりますか? 参照が初期化されないままになりますか、それとも何か不足していますか?

4

6 に答える 6

6

何かが欠けています - それは完全に正当なコードであり、実際、そのようなコードは条件演算子の最も一般的で最良の使用法の 1 つです。コードがページに配置されているのと同じ順序でコンパイラが内部的に処理を行う必要があると考えるのは常に間違いです。条件演算子 (これは単なる別の式です) を評価し、その結果を初期化を実行します。

goto に関しては、初期化で使用する方法はありません。また、例外がスローされた場合、参照は最初から作成されていないと見なされます。

于 2009-08-20T09:40:00.793 に答える
5

より簡単な例:const int x = foo();

この定数も初期化する必要があり、そのfoo()ために呼び出す必要があります。これは必要な順序で行われます: x は foo が戻ったときにのみ存在します。

追加の質問に答えるには: foo()wouldの場合、例外はどこかthrowでキャッチされます。明らかに囲まれたそのためcatch()try{}ブロック。したがって、すでに範囲外であり、値が得られなかったことは関係ありません。例外がない場合は、プログラム (を含む) はなくなっています。catch()const int x = foo();const int xcatchconst int x

C++ には random がありませんgoto。彼らは中に飛び込むことができますfoo()が、それは問題ではありません。foo()まだ戻らなければなりません。

于 2009-08-20T10:04:01.523 に答える
2

CheckCondition() が実行されている間、refStr は存在しますが、まだ初期化されていないことがわかります。

言語弁護士の観点からは、これは間違っています。初期化中、refStrまだ存在しません。ビジュアル デバッガーが誤解を招くヒントを提供していると思います。

初期化内のコードがエラー状態につながる場合、refStr存在しません。

于 2009-08-20T09:41:57.920 に答える
2

これは完全に合法です。これが正常に終了し、参照が有効なオブジェクトにバインドされるか、例外がスローされて制御がブロック外に転送され、参照がスコープ内にないため、誰も気にしなくなります。

于 2009-08-20T09:42:23.907 に答える
0

例外として、refStrにアクセスできない場所に移動し、そこからrefStrがある場所に移動することはできません。関数の場合、gotoはCheckCondition()から抜け出すことができず、マクロの場合、gotoを使用することはできません。longjmp()は、例外と同じ効果があります。つまり、refStrにアクセスできない場所に移動します。

于 2009-08-20T09:52:47.787 に答える