4

私はC++インタビューの質問への回答を読みましたが、その中に私を困惑させるものがあります。

Q:C ++コンパイラによって一時変数が作成されるのはいつですか?

A:関数パラメーターが「定数参照」である場合、コンパイラーは次の2つの方法で一時変数を生成します。

a)実際の引数は正しい型ですが、左辺値ではありません

double Cube(const double & num)
{
  num = num * num * num;
  return num;
}

double temp = 2.0;
double value = cube(3.0 + temp); // argument is a expression and not a Lvalue

b)実際の引数は間違ったタイプですが、正しいタイプに変換できるタイプです。

 long temp = 3L;
 double value = cuberoot(temp); // long to double conversion

私の質問は、関数の引数がconst参照になると、コンパイラが一時変数を生成するのはなぜですか、それは自己矛盾ではありませんか?また、関数Cubeはconst引数を変更するため、コンパイルに失敗する必要がありますか?

4

7 に答える 7

7

ここでは、自己矛盾するものは何も見られません。引数が左辺値でない場合、またはタイプが間違っている場合、明らかな理由により、参照を引数に直接付加することはできません。したがって、正しいタイプの中間一時的なものが必要です。代わりに、参照はその一時的なものに添付されます。

Cube関数は値を変更しようとするため、実際に壊れています(形式が正しくありません)const

于 2010-10-04T17:52:11.877 に答える
3

私には間違っているように見えます-そしてgccはエラーを生成します:

const_ref.cpp: In function ‘double cube(const double&)’:
const_ref.cpp:3: error: assignment of read-only reference ‘num’
于 2010-10-04T17:52:47.940 に答える
2

コンパイラーは一時変数を生成できます。する必要はありません。

そして、はい、Cube実際にコンパイルするべきではありません。

于 2010-10-04T17:52:57.063 に答える
1

式の結果(暗黙的なキャストの結果を含む)をconstへの参照に渡すことができます。理論的根拠は、(const X & value)タイプXのコピーコストに応じて、使用する方が安価かもしれませんが(X value)、効果はほとんど同じであるということです。value使用されますが、変更されません(一部の危険なconst-castingを除く)。したがって、一時オブジェクトを作成して関数に渡すことは無害です。

長い温度が長い温度に戻されると予想されるなど、予期しない(そして悪い)ことが起こる可能性があるため、pointer-to-constまたはreference-to-non-constを使用してこれを行うことは許可されていません。起こりそうです。

あなたはnum = num * num * num;無効であることについて正しいです。それはテキストのバグですが、それによってなされた議論は成り立ちます。

于 2010-10-04T17:58:22.527 に答える
0

どちらの例でも、正しいタイプの非一時オブジェクトがないためです。

于 2010-10-04T17:53:06.383 に答える
0

関数キューブがコンパイルに失敗することについては正しいと思います。とにかく、それは失敗するはずです、そしてそれは私のコンパイラ(VC ++ 2008)で起こります。

一時的なものを作成することに関して:

const参照をバックアップするための一時的な値は、実際の引数が作成されるたびに作成されます。

i)参照に対して正しいタイプではなく、ii)暗黙的に正しいタイプに変換される可能性があります。

例a)の質問からdouble、値を保持するための一時的なものが作成されます3.0 + temp。次に、一時的なものを参照してCube()呼び出されます。constこれは、3.0 + tempそれが変数ではなく(右辺値であり、式の結果である)、メモリアドレスがなく、参照を戻すことができないため、参照を作成できないためです。暗黙的に、コンパイラは一時的なものを作成し、doubleそれに値を割り当てます3.0 + temp

例b)ではlong、がありますが、関数には。が必要doubleです。コンパイラは暗黙的にaをに変換longdoubleます。これを行うには、一時的なを作成し、doubleそれに変換された値を割り当ててから、一時的なものへの参照をtemp作成し、constその参照をに渡します。cuberoot

于 2010-10-04T17:53:18.503 に答える
0

はい。ここに示したように、Cube()はコンパイルに失敗するはずです。

于 2010-10-04T17:54:41.273 に答える