問題タブ [lvalue-to-rvalue]
For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.
c++ - 標準では、間接参照を適用するときにポインター変数の左辺値から右辺値への変換が義務付けられていますか?
TL;DR
次のコードがあるとします。
インダイレクションを適用する前にの左辺値から右辺値への変換が*ptr
必要ですか?ptr
標準は、多くの場所で左辺値から右辺値へのトピックをカバーしていますが、 * 演算子がそのような変換を必要とするかどうかを判断するのに十分な情報を指定していないようです。
詳細
左辺値から右辺値への変換については、N3485のセクション左辺値から4.1
右辺値への変換パラグラフ1で説明されており、次のように述べられています ( employment mine going forward ):
非関数型、非配列型 T の glvalue (3.10) は prvalue に変換できます。glvalue が参照するオブジェクトが T 型のオブジェクトではなく、T から派生した型のオブジェクトでもない場合、またはオブジェクトが初期化されていない場合、この変換を必要とするプログラムの動作は未定義です .[...]
それで*ptr = 0;
、この変換が必要ですか?
4
セクションパラグラフ1に行くと、次のように書かれています。
[...]必要に応じて、式を 必要な変換先の型に変換するために、標準の変換シーケンスが式に適用されます。
では、いつ必要なのですか?セクション5
Expressionsを見ると、左辺値から右辺値への変換はパラグラフ9で言及されています。
glvalue 式が、そのオペランドの prvalue を予期する演算子のオペランドとして現れるときはいつでも、左辺値から右辺値へ (4.1)、配列からポインターへ (4.2)、または関数からポインターへ (4.3) の標準変換が行われます。式を prvalue に変換するために適用されます。[...]
そしてパラグラフ11には次のように書かれています:
一部のコンテキストでは、式はその副作用のためにのみ表示されます。このような式は破棄値式と呼ばれます。[...] 左辺値から右辺値への変換 (4.1) は、式が volatile 修飾された型の左辺値であり、次のいずれかである場合にのみ適用されます [ ...]
どちらの段落もこのコード サンプルには適用されないようで、5.3.1
単項演算子の段落1には次のように書かれています。
単項 * 演算子は間接参照を実行します。それが適用される式は、オブジェクト型へのポインター、または関数型へのポインターであり、結果は、式が指すオブジェクトまたは関数を参照する左辺値になります。式の型が「T へのポインタ」の場合、結果の型は「T」になります。[ 注: 不完全な型 (cv void 以外) へのポインタによる間接化は有効です。このようにして得られた左辺値は、限られた方法で使用できます (たとえば、参照を初期化するため)。この左辺値は、prvalue に変換してはなりません。4.1 を参照してください。—終わりのメモ]
ポインターの値を必要としないようで、ポインターの変換の要件が見当たりません。何か不足していますか?
なぜ私たちは気にするのですか?
インダイレクションを適用する前に左辺値から右辺値への変換が必要なため、初期化されていないポインターの使用は未定義の動作であると主張する他の質問の回答とコメントを見てきました。ptr
例: C++ 標準は、初期化されていないポインターの逆参照が未定義の動作であると正確にどこで言っていますか? はこの議論を行っており、標準の最近のドラフト バージョンのいずれにも示されている内容と議論を一致させることはできません。私はこれを数回見たので、明確にしたいと思いました。
上記のリンクされた質問で指摘したように、未定義の動作に到達する他の方法があるため、未定義の動作の実際の証明はそれほど重要ではありません。
c++ - 2 つの演算子による C++11 のあいまいなエラー (1 つの左辺値と 2 つ目の右辺値)
下部に更新します。
void tree::operator = ( tree t ) で右辺値を使用するようにしたい (この場合、一般的に効率のためにそれらを別の方法で処理したい)
私はそれをコーディングし、右辺値を使用するように std::move を使用しましたが、コンパイラはどの演算子を選択すればよいかわからないと言っています。彼は右辺値を使用してそれを選択すべきではありませんか?
コード:
コンパイラ エラー:
私はclang-503.0.38を使用しています。(ただし、gcc 4.8 でも同じエラーです)
アップデート
わかりました、今私は持っています:
そしてそれは働いています。明日、これから学んだことを回答として投稿します。
c++ - 型の非 const 参照の無効な初期化
printAge
次のコードでは、一時オブジェクトを引数として関数に渡すことができません。
私が得るエラーは次のとおりです。
これは、rValue を期待する関数に lValue を渡すことに関係していることに気付きました... std::move などを使用して lValue を rValue に変換する方法はありますか? 定数パラメーターを取得しようとしましたが、うまくいかないようです。
c++ - 左辺値から右辺値への変換の例を理解する
このコード (C++14 ドラフト標準[conv.lval]の例) が の未定義の動作を呼び出す方法を理解するのに苦労していますg(false)
。constexpr
がプログラムを有効にするのはなぜですか?
また、「アクセスしない」とはどういう意味y.n
ですか?への両方の呼び出しでg()
、データ メンバーを返しているn
のに、最後の行でアクセスしないと表示されているのはなぜですか?
c++ - ここで右辺値参照はどのように機能しますか?
次のコードに困惑しています。
その出力は1
. これがどのように機能するかわかりません。はstatic_cast
、左辺値x
を xvalue にキャストし、それを に代入することになっていrvx
ます。rvx
インクリメントすると が変化するのはなぜx
ですか? これは、変換された左辺値から右辺値が本質的に同じメモリ位置にあるためですが、現在は右辺値と見なされているためですか? 私は、どういうわけかキャストがその引数から一時的なものを作成するという印象を受けました (これはおそらく誤りです)。
c++ - std::move は、非 const 参照を取るコピーコンストラクターでどのように機能しますか?
私は std::move について読んでいました。かなりの資料に基づいて、std::move は引数の型を右辺値参照に変換する単なる関数であると結論付けました。
また、右辺値参照は、引数を const 参照として受け取る関数で使用できることも読みました。オブジェクトの内容が変更されないことが保証されているため、これは意味があります。
これらのアイデアを検証するために、以下にあるクラスを使用して非常に簡単な実験を行いました。
オブジェクトt1を作成し、 std::moveを使用して右辺値参照に変換し、copy-constructor を呼び出して別のオブジェクトt2を作成しようとしました。
不思議な部分は、move-constructor を提供しなくても、意図的にそのパラメーターを非 const 参照として定義した copy-constructor で動作することです。
ただし、std::move がt1の型を右辺値参照に変換する場合、コンパイラはそれを左辺値参照にどのようにバインドできますか?
ところで、「Microsoft(R) Microsoft Visual Studio 2012 バージョン 11.0.50727.1」を使用しています。
ここで何が欠けているのか説明してもらえますか?
どうもありがとうございました。
c - C の二分探索木からノードを削除する
二分探索木からノードを削除しようとしています。しかし、関数をテストしたい場合、「ケース 3: 2 人の子供」でエラー メッセージが表示されます。
この行により、エラー メッセージが表示されます。それは言います:左オペランドは左辺値でなければなりません。私はCと二分探索木が初めてです。なぜこの行が機能しないのかわかりません。削除機能を実装する方法について、インターネット上で多くのアイデアを見つけました。そして、これらのアプローチはすべて、このコード行を使用します。
以下は完全な関数です。
(greaterThan、lessThan、toLowerCase は私が実装したヘルパー関数です。確かに正常に動作しています)
この行が機能しない理由を誰かに教えていただければ幸いです。そして、このエラーを修正する方法。
ありがとう!