間違った形式:
int &z = 12;
正しい形式:
int y;
int &r = y;
質問:
最初のコードが間違っているのはなぜですか?タイトルの誤りの「意味」とは?
間違った形式:
int &z = 12;
正しい形式:
int y;
int &r = y;
質問:
最初のコードが間違っているのはなぜですか?タイトルの誤りの「意味」とは?
(ostringstream() << "x=" << x).str()
回答:
C ++ 03 3.10 / 1によると、「すべての式は左辺値または右辺値のいずれかです。」左辺値と右辺値は、オブジェクトではなく式のプロパティであることを覚えておくことが重要です。
左辺値は、単一の式を超えて存続するオブジェクトに名前を付けます。たとえば、obj
、*ptr
、ptr[index]
、および++x
すべて左辺値です。
右辺値は、それらが存在する完全な式の終わり(「セミコロン」)で蒸発する一時的なものです。たとえば、1729
、x + y
、std::string("meow")
、およびx++
すべての右辺値です。
address-of演算子では、その「オペランドは左辺値でなければならない」必要があります。1つの式のアドレスを取得できる場合、その式は左辺値です。それ以外の場合は、右辺値です。
&obj; // valid
&12; //invalid
int & = 12;
が無効である理由を簡単に答えるために、標準では、文字列リテラルは左辺値であり、他のリテラルは右辺値であるとされています。
std::string("meow")
、型のオブジェクトを作成し、std::string
このオブジェクトを指定する右辺1729
値を生成します。副作用はなく、値を生成します。タイプの右辺値としての1729 int
。
"Lvalues name objects that persist beyond a single expression."
は100%正しいステートメントです。それどころか、(const int &)1
これは「名前付き」オブジェクトではないため、例は正しくありません。
int &z = 12;
右側でint
は、型の一時オブジェクトが整数リテラルから作成されますが、一時オブジェクト12
を非const参照にバインドすることはできません。したがって、エラー。それは同じです:
int &z = int(12); //still same error
なぜ一時が作成されるのですか?参照はメモリ内のオブジェクトを参照する必要があり、オブジェクトが存在するためには、最初に作成する必要があります。オブジェクトには名前がないため、一時オブジェクトです。名前はありません。この説明から、2番目のケースが問題ない理由がかなり明らかになりました。
一時オブジェクトはconst参照にバインドできます。つまり、次のことができます。
const int &z = 12; //ok
完全を期すために、C ++ 11では一時オブジェクトにバインドできる右辺値参照が導入されていることを付け加えておきます。したがって、C ++ 11では、次のように記述できます。
int && z = 12; //C+11 only
の&&
代わりがあることに注意してください&
。また、それconst
はもう必要ないことに注意してください。z
バインドするオブジェクトは、integral-literalから作成された一時オブジェクトですが、は12
。
C ++ 11では右辺値参照が導入されたため、int&
以降、左辺値参照と呼ばれるようになりました。
12
は、で参照されるデータとは異なり、変更できないコンパイル時定数int&
です。あなたにできることは
const int& z = 12;
void f( vector<int> const & )
変更されないベクトルを渡すのが慣用的な関数について考えてみましょう。ここでの問題は、それf( vector<int>(5) )
が正しくないことであり、ユーザーvoid f( vector<int> v ) { f(v); }
は些細な別のオーバーロードを提供する必要があります。
f( vector<int>(5) )
で、コンパイラーは一時的なものを作成し、その一時的なものに参照をバインドします。同様に5
直接からの暗黙の変換があった場合。これにより、コンパイラーは関数の単一の署名を生成でき、関数の単一ユーザー実装が可能になります。それ以降、一貫性を保つための定数参照の残りの使用についても、同様の動作が定義されます。
T const & r = *ptr;
、r
関数でのその後の使用は、に置き換えることができ、実行時に存在する必要*ptr
はありr
ません)または、エイリアスするオブジェクトのアドレスを保持することによって実装する必要がある場合があります(参照をオブジェクトのメンバーとして格納することを検討してください)。これは、自動逆参照ポインターとして実装されます。
これらはC ++言語のルールです:
12
)で構成される式は「右辺値」ですint &ri = 12;
形式が正しくありませんこれらはC ++ルールであることを理解する必要があります。彼らはただです。
わずかに異なるルールで、異なる言語、たとえばC ++ 'を発明するのは簡単です。C ++ 'では、右辺値を使用して非定数参照を作成することが許可されます。ここには矛盾したり不可能なことは何もありません。
しかし、プログラマーが意図したものを取得できない可能性があるリスクの高いコードが許可されるため、C ++設計者はそのリスクを回避することを正しく決定しました。
参照は、変更される可能性のあるもの(左辺値)への「隠しポインター」(null以外)です。それらを定数に定義することはできません。それは「可変」のものでなければなりません。
編集::
私は考えています
int &x = y;
ほぼ同等
int* __px = &y;
#define x (*__px)
ここ__px
で、は新しい名前であり、参照#define x
の宣言を含むブロック内でのみ機能しx
ます。
const
:)
const