問題タブ [perfect-forwarding]
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++ - G++ 4.5.0 の std::forward_as_tuple
私はこの関数を差し迫って必要としていますstd::forward_as_tuple
が、GCC 4.5.0 の使用に制限されています (これは自分自身を配置するのに悪い状況であることはわかっていますが、それは私にとって多くの問題を解決するので、皮肉な発言は控えてください最小)。<tuple>
ヘッダーには関数が含まれていないようです(本来あるべき)ので、私の質問は次のとおりです。
- 他のヘッダーに隠されていますか?(これは以前にも発生しましたが、特定するのは困難です。)
- 独自の実装を展開することは可能ですか? つまり、GCC 4.5.0 で実装されているc++11 の部分で実装可能ですか? 誰かが実際にこれを行う方法を知っている場合のボーナス。
c++ - C ++ 11のすべて/ほとんどのセッター関数は、ユニバーサル参照を受け入れる関数テンプレートとして作成する必要がありますか?
メンバー変数、コピー可能および移動可能なタイプのそれぞれ、および対応するセッター関数をX
持つクラスについて考えてみます。C ++ 98では、の定義は次のようになります。N
N
X
上記のクラスのセッター関数はX
、左辺値と右辺値の両方の引数にバインドできます。実際の引数によっては、これにより一時的なものが作成され、最終的にはコピーの割り当てが発生する可能性があります。このため、コピーできないタイプはこのデザインではサポートされていません。
C ++ 11では、移動セマンティクス、完全な転送、およびユニバーサル参照(Scott Meyersの用語)があり、次のように書き直すことで、セッター関数をより効率的かつ一般的に使用できます。
ユニバーサル参照は、/ non -、/ non- const
、および一般に任意の変換可能なタイプにバインドできるため、一時的なものの作成を回避し、値をに直接渡すことができます。コピー不可能な移動可能なタイプがサポートされるようになりました。おそらく望ましくないバインディングは、を介して、またはを介して排除できます。const
volatile
volatile
operator =
static_assert
std::enable_if
だから私の質問は:設計ガイドラインとして、C ++ 11のすべての(たとえばほとんどの)セッター関数は、ユニバーサル参照を受け入れる関数テンプレートとして作成する必要がありますか?
より厄介な構文と、これらのセッター関数でコードを記述するときにIntellisenseのようなヘルパーツールを使用できないことは別として、「可能な場合はいつでもユニバーサル参照を受け入れる関数テンプレートとしてセッター関数を書く」という仮定の原則に関連する欠点はありますか?
c++ - 移動セマンティクス用に最適化されていない完全な転送を使用する可変個引数テンプレート
こんにちは、作成した variadic add テンプレートで move ctor が呼び出されないという問題があります。
c++ - 可変テンプレート引数の完全転送
一般的なシグナル/スロット システム用に次の実装を作成しました。
その後、次の単純なケースを使用してクラスをテストしました。
ケース 1 は問題なくコンパイルされます。一方、ケース 2 では、GCC 4.7.2 で次のエラーが生成されます。
この問題は完全転送と関係があることを理解しています(および後者に対する私の誤解)。ただし、私は std::make_shared() と std::make_tuple() の実装からインスピレーションを得ており、可変引数をデリゲートに転送する方法に違いは見られません。唯一の注目すべき違いは、make_shared() と make_tuple() の両方が、上記の Signal 実装などのクラス テンプレートではなく、関数テンプレートであることです。
- 編集 -
さまざまなコメントに応えて、前述の問題の影響を受けない新しいバージョンの Signal クラス実装を以下に示します。さらに、connect 関数によって返される不透明なトークンを使用してデリゲートを切断できるようになりました。結果は、他の実装 (boost::signal など) ほど柔軟で強力ではないかもしれませんが、少なくとも、シンプルで軽量であるという利点があります。
c++ - 純粋な転送のイディオム
この質問とこの他の質問を組み合わせて、次の(実際には非常に単純な)解決策にたどり着きました。アイデアは、実際の関数の範囲内でのみ型エイリアスを使用可能にし、適切なポイントでテンプレートの条件を確認することです。
このコードを使用すると、快適な方法で必要なエイリアスまたは条件を追加できます。このコード:
になります(のみsome_fun
):
上記の 2 番目の質問で@ipcfirewall
が示しているように、の目的は、デフォルトのテンプレート引数として定義されたローカル型エイリアスを再配置できる引数を吸収することです。
また、これにより、他のより深い問題を回避するための便利な方法が利用可能になります。事前に既知のタイプの完全な転送を行うためだけに関数をパラメトリックにしたい場合。たとえば、次の状況では:
完全な転送メカニズムを使用して初期化する場合_str
、他のテンプレート引数とあいまいになることは避けられません。これは、次の追加マクロを使用して簡単に回避できます。
fwStr
タイプstd::string
、std::string&
、またはそれらの定数バージョンでない場合はstd::string&&
、他のコンストラクターが選択され、他のコンストラクターがない場合は、std::enable_if<false, void>::type
存在しないというコンパイラ エラーがスローされます。
質問: C++ では常にマクロの使用を避けることが望ましいですが、よく知られているテンプレートは冗長であり、これらの状況 (特に 2 番目の状況) は非常に一般的です。少なくとも私の経験では。次に、これらのマクロは非常に便利です。
この状況でマクロを使用するのは危険ですか? これは一般的に良いものですか、それとも有用ですidiom
か、それとも何もないようですか?
c++ - C++ RValue 参照パラメーターを const としてマークすることはありますか?
私は右辺値をサポートし、セマンティクスを移動するために、テンプレート ファクトリ関数を std::forward を使用する (そして理解する) ように切り替えてきました。テンプレート クラスの通常のボイラープレート ファクトリ関数は、常にパラメーターを const としてマークしています。
期待どおりにコンパイルされます。最初に MakeMyPair を変換してパラメータも const として渡しましたが、これは XCode 4.6 を使用している Mac ではコンパイルされません。
'MakeMyPair_Forward' の呼び出しに一致する関数がありません 候補関数 [T = int、U = bool] は実行できません: 第 1 引数の 'int' から 'const int &&' への既知の変換はありません
これはhttp://en.cppreference.com/w/cpp/utility/forwardから理にかなっています。これは const が推定され、左辺値を渡していることを示しています。
- wrapper() への呼び出しが右辺値 std::string を渡す場合、T は std::string (std::string&、const std::string&、または std::string&& ではない) と推定され、std::forward は保証します。右辺値参照が foo に渡されます。
- wrapper() への呼び出しが const 左辺値 std::string を渡す場合、T は const std::string& と推定され、std::forward は const 左辺値参照が foo に渡されることを保証します。
- wrapper() への呼び出しが非 const 左辺値 std::string を渡す場合、T は std::string& と推定され、std::forward は非 const 左辺値参照が foo に渡されることを保証します。
const の削除は、右辺値と左辺値で必要に応じて機能します。MakeMyPair_Forward のパラメーターの const で機能するのは、右辺値を型として渡すことだけです。
では、質問です。パラメータとして渡すときに右辺値参照を const としてマークすることは意味がありますか? 右辺値を変更できるわけではなく、一時的なものです。コードを調べて修正した後、 const でコンパイルされたことに少し驚きました。右辺値パラメーターを const としてマークするのはなぜですか? 右辺値を取る API のみを提供することがポイントでしょうか? もしそうなら、左辺値参照を防ぐために代わりに型特性を使用しませんか? https://stackoverflow.com/a/7863645/620304
ありがとう。
c++ - ユニバーサル参照を保存する方法
クラス内にユニバーサル参照を保存する必要があります(参照された値はクラスよりも長く存続すると確信しています)。そうする標準的な方法はありますか?
これは私が思いついたものの最小限の例です。うまくいくようですが、うまくいったかどうかはわかりません。
私の推論は正しいですか、それとも微妙なバグにつながるのでしょうか? また、コンストラクタを記述するためのより良い (つまり、より簡潔な) 方法はありますか? binder(F&& f, X&& x)
これらは右辺値参照であるため、機能しませんbinder(f, i)
。
c++ - 完全転送 拾わない方法
テンプレートを使用しないため、次のコードで SFINAE エラーが発生します。結果として、引数を完全に転送しようとしています。どんなアイデアでも。
ブレア
c++ - 中括弧で囲まれた初期化子と完全転送を組み合わせる方法
このコードは次のようにコンパイルされます。
同様にそのように:
しかし、これはしません:
その理由は、3 つ目が を呼び出すためですがtuple(const Types&...)
、恣意的な制限のようです。
C++ 11 は可変個引数テンプレートでこれを表現できませんか、それとも可能ですか?