問題タブ [template-aliases]
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.7) は、エイリアス定義に を含めることに非常に満足してい= double
ますが、これを無視しているようです。
エイリアスを「特殊化」するようなことも試しましたが、コンパイラーが失敗しました。
質問
デフォルトの使用が許可されていないのに、コンパイラが定義でデフォルトを受け入れるのはなぜですか? 第二に、これを達成する方法はありますか?
動機
この例は非常に単純ですが、私の実際のコードでは、エイリアスにより多くの入力が節約されます (複数のテンプレート パラメーターがあります)。
c++ - 部分的なテンプレートの特殊化に関する g++ のバグ
g++ (バージョン 4.8.1_1、Macports) および clang++ (バージョン 3.3、Macports) 用の TMP を多用するコードを作成しています。g++ は次のコード リストをUNBRIDLED FURYで拒否しますが、clang++ はそれを優雅に見事にコンパイルします。
- 正しいのはどのコンパイラですか? (私はそれが g++ であると強く疑っていますが、バグ レポートを提出する前に他の人から安心を得たいと思っています。)
- 提案する簡単またはエレガントな回避策はありますか? (テンプレート エイリアスを使用する必要があるため、g++ にコードを受け入れさせる構造体に切り替えることはオプションではありません。)
これがあなたのために作られたコードリストです。
g++ の出力は次のとおりです。
これがclang ++の出力です:
ご協力いただきありがとうございます!
c++ - テンプレート エイリアスを特殊化するための最良の方法 (または回避策)
私は現在、小さなメタプログラミング ベースのコンパイル時計算ライブラリを実装しています。
結果の typedef を持つ演算子の基本クラスを定義した場合 (std::integral_constant
ライブラリに沿って統一されたインターフェイスを提供するために、生の整数値の代わりに as 値のような積分ラッパーを使用することにしました)、および n-ary 演算子の基本クラスを定義した場合、演算子に少なくとも 1 つのオペランドがあるかどうかをチェックします。
そこで、単項演算子と二項演算子のエイリアスを次のように定義しました。
その演算子インターフェイスは、以下の比較演算子のように、カスタム演算子をエイリアスとして定義するために使用されます。
ここで、独自のクラスにカスタムの等価演算子を実装するとします。例えば:
等価演算子がエイリアシングではなく継承時に作成された場合、これはテンプレートの特殊化によって簡単に実行できます。
テンプレート エイリアスを特殊化できないことはわかっています。
私の質問は次のとおりです。テンプレート エイリアスの代わりに継承設計を使用せずに、この種のテンプレート エイリアスを特殊化する方法はありますか?
c++ - 部分的なテンプレート バインディング、タイプとして新しいテンプレートを作成
テンプレートをパラメーター型に部分的にバインドする方法はありますか? たとえば、次のテンプレートがあります。
そして、テンプレートクラスをパラメーターとして受け取る別のテンプレートがあり、最初のタイプでそのインスタンスを作成できることを期待しています:
これは、変更なしのような単純なテンプレートを受け入れtemplate<typename T>
ます。私が今やりたいことは、generic
テンプレートを部分的にバインドし、それのみQ
を指定して に渡すことwrapper
です。おそらく次のような構文を作成します。
継承を使用して、必要なものをほとんど取得できることを知っています。
ただし、基本クラスで定義されたコンストラクターと演算子で問題が発生するため、これを回避したいと考えています。
c++ - ネストされたテンプレートへのテンプレート テンプレート エイリアス?
typename F <T>::type
テンプレート エイリアスは、 just F <T>
、 where T
、type
are などの型を単純化するのに非常に便利です。
のようなテンプレートについても同じことをしたいと思います。つまり、とはテンプレート構造体またはエイリアスF <T>::map
に単純化します。F <T>
T
map
たとえば、次の定義を検討してください。
現在、次のように機能します。
これははるかに便利ですが、失敗します:
(が構造体として定義されていneg = neg_f <F>::template map
ても、 で失敗します)。map
上記の定義はneg
、「テンプレート テンプレート エイリアス」のようにする必要があるようです。
しかし、明らかにそのようなことはありません。
それで、解決策はありますか、それとも一緒にいるべきneg_f <pred>::map
ですか?
c++ - テンプレート typedef の新しい「using」構文によって解決された問題は何ですか?
C++11 では、次のような方法で「型エイリアス」を作成できます。
しかし、これは、テンプレートの typedef が次のようになると予想されるものとは異なります。
ここで疑問が生じます - なぜ彼らは新しい構文を考え出す必要があったのでしょうか? typedef
古い構文で機能しなかったのは何ですか?
最後のビットがコンパイルされないことはわかっていますが、なぜコンパイルできないのでしょうか?
c++ - テンプレート引数としての可変個引数テンプレート エイリアス
最初にいくつかのコード、次にいくつかのコンテキスト、次に質問:
clang 3.3 と gcc 4.8.1 の両方がこれをエラーなしでコンパイルし、恒等メタ関数を に適用するint
ため、両方の式がデフォルトint
(ゼロ) に評価されます。
id
それがtemplate <typename>
しばらくの間apply1
であるという事実は、そもそも私が心配していたことをapply2
期待しています。ただし、この例が機能することは非常にtemplate <typename...>
便利です。apply1
apply2
一方、このようなテンプレート エイリアスは、ここでは再現できない実際のコードで深刻な問題を引き起こします。gcc では頻繁に内部コンパイラ エラーが発生し、clang ではあまり頻繁に予期しない動作が発生します (より高度な SFINAE テストでのみ)。
数か月の試行錯誤の後、(実験的な) gcc 4.9.0 にコードをインストールして試してみると、次のエラーが表示されます。
さて、このコードはずっと有効ではなかったようですが、gcc はエラーを報告する代わりにさまざまな方法でクラッシュしました。興味深いことに、は同等apply1
にapply2
見えますが、エラーが報告されるのはapply2
(実際にははるかに便利です) だけです。クランに関しては、私は本当に言うことができません。
実際には、gcc 4.9.0 に合わせてコードを修正する以外に方法はないようです。
理論的には、標準が何を言っているのか知りたいです: このコードは有効ですか? そうでない場合、 の使用もapply1
無効ですか? またはのみapply2
?
編集
これまでに発生したすべての問題は、テンプレートの構造体ではなく、テンプレートのエイリアスを参照していることを明確にするために。たとえば、次の変更を検討してください。
これ0
は、clang 3.3、gcc 4.8.1、gcc 4.9.0 の両方の場合で、正常にコンパイルされ、印刷されます。
ほとんどの場合、私の回避策はエイリアスの前に中間テンプレート構造体を導入しています。ただし、メタ関数を使用して一般的な SFINAE テストをパラメーター化しようとしています。この場合、構造体をインスタンス化してはならないため、エイリアスを直接使用する必要があります。アイデアを得るために、実際のコードの一部をここに示します。
c++ - テンプレート引数としての可変個引数テンプレート エイリアス (パート 2)
これは別の質問のフォローアップです。それは同じ問題に言及していますが (私は願っています)、それを説明するためにまったく異なる例を使用しています。その理由は、前の例では実験的な GCC 4.9 のみがコンパイル エラーで失敗したためです。この例では、Clang と GCC 4.8.1 もさまざまな方法で失敗します。Clang は予期しない結果を生成し、GCC 4.8.1 は別のエラー メッセージを報告します。
前の質問への回答は、多かれ少なかれ、コードが有効であり、問題は GCC の実験的バージョンにあることを示しています。しかし、この結果は私をもう少し懐疑的にします。私は何ヶ月もの間、関連している(または同じ)と思われる問題に悩まされてきましたが、具体的な例を示すのはこれが初めてです。
だから、ここにいくつかのコードがあります。まず、可変個引数のテンプレート エイリアス メタ関数で指定された任意のテストに SFINAE を適用する一般的なコードF
:
次に、指定されたクラスが という名前の型を定義しているかどうかを確認する特定のテストtype
:
最後に、例:
期待される結果は です0, 1
。クランは言い0, 0
ます。GCC 4.8.1 は言う
そしてGCC 4.9は言う
(行番号は異なる場合があります)。したがって、さまざまな方法ですべてが失敗します。
さて、ここに回避策があります。メタ関数car
は、指定されたパックから最初の型を選択し、テストは として再定義されtype_of2
、現在は可変個です:
これで、3 つのコンパイラすべて0, 1
が期待どおりに動作するようになりました。興味深いことに、GCC のどのバージョンでhas_type
も (使用しない場合でも)削除してhas_type2
、. そうしないと、同様のエラーが発生します。
まとめ: フォームの可変個引数のテンプレート パラメーターを期待する 1 つのテンプレートに問題があることがわかります。
ここで、実際には、次の形式の非可変個のテンプレート エイリアスを入力として指定します。
F
そして最後に、可変個引数であるかのように呼び出します。
これまでのところ、これは有効であるという意見がありますが、現在、3 つのコンパイラが反対しているようです。もう一度質問です。それは有効ですか?
私にとっては、これが有効であるという仮定に基づいて既存のコードのファイルが数十あり、とにかく再設計が必要なので (これらのコンパイラには実際的な問題があるため)、正確な再設計は答えによって異なります。