問題タブ [c++-concepts]
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++ - void_t 「概念を実装できます」?
テンプレート メタプログラミングに関する Walter Brown の CppCon2014 トークの第 2 部を見ていましたvoid_t<>
。Peter Sommerlad はプレゼンテーション中に、私にはよくわからない質問をしました。(リンクは質問に直接行きます。議論中のコードはその直前に行われました)
サマーラッドは尋ねた
ウォルター、それは実際にコンセプトライトを今すぐ実装できるということですか?
ウォルターが答えた
そうそう!私はそれをやった...それはまったく同じ構文を持っていません。
このやり取りは Concepts Lite に関するものだと理解しました。このパターンは本当に汎用性がありますか?どういうわけか、私はそれを見ません。誰かがこのようなものがどのように見えるかを説明 (またはスケッチ) できますか? これは単にenable_if
特徴を定義しているだけですか、それとも質問者が言及していたものは何ですか?
テンプレートは次のvoid_t
ように定義されています。
彼はこれを使用して、型ステートメントが適切に形成されているかどうかを検出し、これを使用してis_copy_assignable
型特性を実装します。
話のおかげで、この例がどのように機能するかは理解できましたが、ここから Concepts Lite のようなものに至る方法がわかりません。
c++ - Boost コンセプト チェック ライブラリを使用してメソッドの戻り値の型を検証することはできますか?
Boostコンセプトチェックライブラリを使い始めました。ただし、ドキュメントを読んだ後、概念のメソッドが特定の型を返すことを確認する方法が見つからないようです。ただし、これも不可能だと言っているものは何も見当たりません。これは奇妙です。
では、戻り値の型が正しくない場合に失敗する概念を書くことは可能ですか?
c++ - C++ の概念をサポートする STL 実装はありますか?
C++ の概念を使用するクラス プロジェクトに取り組んでいます。orなどの概念ドラフト TSからの has 制約をサポートする STL 実装はどこにありますEquality_comparable
かSortable
?
ご協力いただきありがとうございます!
これが私がこれまでに試したことです:
c++-concepts
GCC の SVN からブランチを正常にコンパイルしました。これは維持されているようです (昨日、Andrew Sutton によって最終更新されました)。ただし、このブランチに付属する libstdc++ は、概念に関して更新されていません。
また、次のことを約束するConcepts-Lite (gcc-clite)も試しました。
このコンパイラに同梱されている標準ライブラリには、論文「A Concept Design for the STL」
<type_traits>
にある制約が含まれており、ヘッダー ファイルをインクルードすることでアクセスできます。
ただし、そのページからダウンロードした GCC コードの libstdc++ にも概念がありません。特に、type_traits
ヘッダーは、フォーク元の GCC リビジョンから変更されていないように見えます。
c++ - C++: ポリモーフィック コンテナ / イテレータ vs コンパイル時の概念 / 特性
バックグラウンド
これは純粋に教育目的のためです。背景全体を読みたくない場合は、下部の質問にスキップできます。
Queue インターフェイス (抽象クラス) と、配列のサイズ変更とリンク リストに基づく 2 つの派生実装を作成しました。
STL 準拠のイテレータ (キューは反復可能であってはならないことはわかっています) を使用してキューの要素を処理できるようにしたかったので、for (auto e: c)
orを使用できqueue.begin()
ますqueue.end()
。
私はランタイム ポリモーフィズムを使用しているため、クライアント イテレータ クラスを追加しIQueue
、Pimpl イディオムを使用して、派生キュー クラスで実際の実装固有のイテレータをインスタンス化し、オブジェクトのスライスの問題を回避する必要がありました。したがって、拡張コードは次のようになります。
派生クラスの 1 つはbegin()
/end()
メソッドと派生 Iterator 実装を実装します。
イテレータが機能することをテストするために、次の 2 つの関数があります。
質問
ランタイム ポリモーフィズムを取り除き (IQueue を削除し、イテレータ Pimpl 実装を削除する)、次のようにtestQueue()
/testQueueImpl()
関数を書き直すにはどうすればよいでしょうか。
- 関数は、基底クラスのポインターを持たなくても、Stack 実装と Stack イテレーターを正常にテストできます。
- LinkedListQueue と ResizingArrayQueue の両方がある種のコンパイル時インターフェースに準拠していること (enqueue、dequeue、isEmpty、size メソッドが存在し、begin / end メソッドが存在し、両方のクラスに有効な反復子クラスが含まれている)?
考えられる解決策
1) の場合、テンプレート引数をコンテナー全体に変更するだけで、プログラムは正常にコンパイルされて実行されるようです。しかし、これは begin() / end() / enqueue() メソッドの存在をチェックしません。
2)インターネットで見つけたものから、関連するソリューションには、タイプの特徴/ SFINAE /または概念(コンテナの概念、フォワードイテレータの概念)が含まれるようです。Boost Concepts ライブラリを使用すると、クラスに注釈を付けてコンテナの概念に準拠させることができるようですが、教育目的で自己完結型のソリューション (STL 以外の外部ライブラリなし) に興味があります。
c++ - 「概念の使用を簡素化する」からの C++ 概念の例
Bjarne Stroustrup のミニペーパー「概念の使用を単純化する」を読んでいたときに、次のスニペット (9 ページ) に出くわしました。
明らかに、 であるすべての型
ABx
は であるAx
ため、次のようになります。言い換えれば、一般に、
ACx
の [sic]a()
が と異なることを防ぐ必要がありAx
ますa()
。これら 2 つの が異なる可能性がある場合、上記a()
の呼び出しを受け入れることはできません。g(t)
a()
この例を理解するのに苦労しています。特に、最後の議論がよくわかりません。
- Bjarne の意味
ABx
は ではなくACx
? ([sic] をマークした場所) - Bjarneは、それがとが有効な
X
タイプであることを意味しましたか? のみが有効であれば、適用すべきではないと思うので、あいまいさはありません。a(x)
b(x)
a(x)
template<ABx T> void f(T t);
a()
Bjarne が 2 つの実装が異なる可能性があると主張するとき、彼が何を意味するのかわかりません。それらは同じである必要はありませんか?
Bjarne の例は正しいと確信していますが、私は C++ の概念について十分に知りません。誰かが私を啓発してくれれば幸いです。
c++ - 関数をチェックする概念は、可動のみの引数では機能しません
可動のみの型 (たとえば ) を受け入れるコールバック関数を呼び出す関数がありますunique_ptr
。
このコードをコンパイルしようとすると、BOOST_CONCEPT_ASSERT
行がunique_ptr
. 行を削除すると、コードは正常に機能します。Boost.Concept ライブラリは移動セマンティクスをサポートしていないようです。私自身の概念クラスを書かずに、これに対する回避策はありますか (ちなみに、左辺値と右辺値の両方を引数としてサポートするのは非常に単純ではありません)。
c++ - .net と比較した C++ の所有権の概念
以下は、このトピックに関する現在入手可能な知識から導き出された一連の結論であり、本質的に問題は、これが正しいかどうか、そうでない場合、これらの結論に対する適切な修正は何かということです.
経験豊富な .net 開発者として、私は完全に、すべてのオブジェクト インスタンスがクラウド内のほとんど粒子として存在し、オブジェクト メンバーシップは単にそれらの粒子を相互に関連付けるという考えに完全に慣れています。フレームワーク内のルート オブジェクトへの何らかの参照によってパーティクルまたはパーティクル クラウドをリンクできない場合、それまたはそのメンバーは破棄されます。これは基本的に、参照カウントと、オブジェクトがまだルートへのパスを持っているかどうかの理解を維持するある種のネットワーク分析の結果です。
この構造では、オブジェクトの識別可能なインスタンスを他の多くのオブジェクトから参照 (「所有」) することができ、所有権のネットワークを必要に応じて複雑かつ循環/自己参照にすることができます。
C++ への移行では、メモリ管理のためにこの自由を制限する必要があることがわかります。すべてのオブジェクトには、オブジェクトの有効期間が親によって維持される明確な所有権ツリーが必要です。
ライフタイムは、波括弧で囲まれたコード セクション {} 内の一時的な値のように、スコープによって制約される場合もあります。絶対に避けるべきですが、new
キーワードを使用し、delete
C++ の新しい標準化では、shared_ptr のようなものは、.net マネージ メモリ モデルに近いものを許可するように設計されているようです。これらが、自己参照的ではあるが接続されていないオブジェクト クラウドを破棄するマネージド メモリと同じ利点を提供するかどうかはわかりません。
例は std::list です。私が知る限り、推奨される戦略は、リスト内のオブジェクト インスタンスは、shared_ptr コンストラクトの利点なしで、リストによってのみ所有され、リスト自体の有効期間によって決定される有効期間を持つ必要があるということです。これにより、一時的に呼び出されるコピー コンストラクター、デストラクタ、または単一の具象型を持つリストを必要とする emplace メソッドの使用が必要になります。別の解決策として、オブジェクトへのポインターを格納し、オブジェクトの有効期間を別の場所で管理する必要がありますが、これには明らかな危険が伴います。これはすべて非常に厄介なようです。
.net では、オブジェクトの有効期間が別の方法で管理されるため、リストは親またはガーディアンでなくてもオブジェクトを参照できます。
パフォーマンスに影響を与えるヒープメモリとスタックメモリには違いがあることは知っていますが、このトピックについて詳しくは知りません。
2 つのシステムに対する私の見方は本質的に正しいですか? そうでない場合、どのような修正を提供できますか? それが本質的に正しい場合、大規模で強力で高性能なアプリケーションを作成するために採用する必要がある C++ のメンタル モデルについて説明している文献はありますか? これには、コードのベスト プラクティスと、大規模なアプリケーションを確実に管理するというより抽象的な概念が含まれます。