問題タブ [universal-reference]
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++ - 引数が参照の場合、Variadic テンプレート コンストラクターの選択が失敗する
次のコードがあります。
正常に動作し、印刷されます
ただし、2 番目のオーバーロードの最初の引数が参照の場合、突然 2 番目のオーバーロードが取得されなくなり、コンパイルが失敗します。
どうしてこれなの?それを修正してコピーを避けることは可能ですか?
編集:ユニバーサル参照を使用すると、明らかに再び機能します。私が実際に望んでいるものであるconst
参照も機能しません。
さらに、入力パラメーターを別の値に保存しても (右辺値を避けて)、機能しません。
c++ - 右辺値引数を指定すると、この関数が左辺値参照を返すのはなぜですか?
min
次の関数の定義
問題があります:書くことは完全に合法であるようです
これは、Clang 3.5 および g++ 4.9 でテストされています。
解決策は簡単std::forward
です。引数の「右辺値」を復元するために使用するだけです。つまり、本体を変更してdecltype
、
ただし、最初の定義でエラーが発生しない理由を説明するには途方に暮れています。
転送とユニバーサル参照についての私の理解を考えると、整数リテラルが渡されたときと同じように、 と の両方が引数の型t
をu
推測します。int&&
ただし、 の本体内ではmin
、引数に名前があるため、それらは左辺値です。ここで、条件演算子の非常に複雑なルールが登場しますが、適切な行は次のとおりだと思います。
- E2 [および] E3 はどちらも同じ型の glvalue です。この場合、結果の型と値のカテゴリは同じになります。
したがって、戻り値の型も同様である必要がありますoperator?:
。int&&
ただし、(私が知る限り) Clang と g++ の両方がmin(int&&, int&&)
左辺値参照を返すint&
ため、結果に割り当てることができます。
明らかに私の理解にはギャップがありますが、何が欠けているのか正確にはわかりません。ここで何が起こっているのかを正確に説明できる人はいますか?
編集:
Niall が正しく指摘しているように、ここでの問題は条件演算子 (int&&
期待どおりの型の左辺値を返す) ではなく、decltype
. decltype
言うためのルール
式の値カテゴリが左辺値の場合、decltype は T& を指定します
そのため、関数の戻り値は になりますint&& &
。これは、C++ 11 の参照折りたたみ規則により、プレーンになりますint&
(私の予想に反してint&&
)。
しかし、 を使用すると、 (back)std::forward
の 2 番目と 3 番目の引数をoperator?:
右辺値、具体的には xvalue に変換します。xvalues はまだ glvalues であるため (後ろに追いついていますか?)、同じ条件演算子規則が適用され、同じ型と値カテゴリの結果が得られます。つまりint&&
、xvalue です。
ここで、関数が戻ると、別のdecltype
ルールがトリガーされます。
式の値カテゴリが xvalue の場合、decltype は T&& を指定します
今回は、参照の折りたたみによりint&& && = int&&
、さらに重要なことに、関数は xvalue を返します。これにより、私たちが望むように、戻り値に代入することが違法になります。
c++ - エイリアシングを使用して単一の型へのユニバーサル参照を制限する
パラメーターの 1 つに完全転送を使用したいクラスのメンバー関数があります。ただし、転送される関数は type の単一の引数のみを受け入れるc2Type
ため、呼び出し元の関数も引数のみを受け入れるようにしたいと思いc2Type
ますが、転送を行うには明らかにユニバーサル参照を保持する必要があります。次のようなデフォルトのテンプレートパラメータを使用して達成できるようです:
ただし、いくつかのメンバー関数でこのタイプを確認する必要があります。また、このような長いテンプレートは、使いにくく、読みにくいようです。私がしたいのは、次のisC2Type
ようなエイリアスを作成することです
configurationMessageHandler
テンプレートが次のようになると思いました
しかし、それはコンパイルされません。この場合、エイリアスを適切に使用するにはどうすればよいですか?
c++ - VS 2013 は、テンプレート パラメーターに応じてユニバーサル参照と戻り値の型を使用して関数テンプレートを特殊化できません。
VS 2013 は、次のコードで関数テンプレートを特殊化できないと言います。
で置き換えるか、ユニバーサル参照をで置き換えtypename T::result_type
ても、文句はありません。int
T&&
T&
私の意見では、上記のコードは正しいです。これはコンパイラのバグですか、それとも何か間違っていますか?