問題タブ [explicit-instantiation]

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.

0 投票する
2 に答える
1099 参照

c++ - テンプレート クラスのメソッドを条件付きで削除する

背景: STL を使用すると、テンプレート コードが肥大化するためにビルドが遅くなります。多くの場合、同じメソッドが多くの異なる翻訳単位で個別にインスタンス化され、コンパイルと最適化が何度も行われます。このテンプレート クラスのオブジェクト コードの重複を回避する 1 つの方法は、明示的なテンプレートのインスタンス化extern テンプレート宣言を使用することですが、STL 実装はそれらをサポートしていません。std::vector<T>明示的なインスタンス化をサポートする同等のものを実装しようとしています。


質問: 私はテンプレート クラスを持っています。テンプレート引数がいくつかの条件を満たさないvector<T>場合、そのメソッドのいくつかを削除したいと考えています。Tさらに悪いことに、追加の要件があります。

  1. が条件を満たすvector<T>かどうかに関係なく、を明示的にインスタンス化できる必要があります。T
  2. 誰かが条件付きで削除されたメソッドを呼び出すと、コンパイル エラーが発生するはずです。
  3. そのような条件がいくつかあり、それぞれに依存する一連のメソッドがあります。

考察: たとえば、がコピー構築vector<T>::push_back(const T&)可能でない場合、このメソッドは機能しません。T

このメソッドの実装をそのままにしておくと、たとえばを明示的にインスタンス化するvector<unique_ptr<int>>と、コピーできないため、コンパイラはエラーを生成しますunique_ptr<int>。これは要件 1 に反し、目的のコード肥大化の最適化を不可能にします。

の 2 つの異なる実装を作成できますvector<T>::push_back(const T&)。1 つはコピー構築可能な型用で、もう 1 つはその他の型用です。これは、SFINAE オーバーロードまたはヘルパー テンプレート クラスを使用して行うことができます。コピー構築不可能なケースの実装は、単純に例外をスローするか、終了を呼び出すことができます。push_backただし、メソッドを呼び出すと、vector<unique_ptr<int>>実行時にのみクラッシュします。要件 2 で述べたように、コンパイル エラーは発生しません。

最後に、いくつかの条件があり、それぞれがいくつかのメソッドを除外します。型Tには、次のプロパティがさまざまな組み合わせで欠けている可能性があります: コピー構築可能、コピー割り当て可能、デフォルト構築可能、移動構築可能。関連する質問の解決策は、要件 3 を満たさない 1 つの条件でのみ機能するようです。

vector<T>私が残した唯一のアイデアは、プリプロセッサのハックと組み合わせて、全体のある種の部分的な特殊化を使用することです。しかし、これには 16 の個別の専門化が必要であり、ひどいように聞こえます。

PS STL 設計は本質的に暗黙的なインスタンス化のメカニズムに依存しているため、それらによって引き起こされるコードの肥大化を減らすことが非常に難しくなっていることが明らかになりました。