問題タブ [template-specialization]

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 投票する
3 に答える
129 参照

c++ - コンパイラに適切なテンプレートの特殊化を使用させる方法は?

次の簡略化されたバージョンのコードについて考えてみます。テンプレートクラスA、テンプレート関数、またはなどFillの基本的な型を処理するための関数の特殊化と、以下を処理するための別の特殊化があります。intcharA

コンパイラーがパラメーターを適切なテンプレートの特殊化に一致させることに成功していることに驚いていますが、これは問題なく機能します。

問題はtypedef、の使用を容易にするいくつかのsに付属していますA<x>。簡略化したバージョンは次のとおりです。

コンパイラーは、型A12が実際にあることを検出せずA<12>、関数の誤った特殊化を使用します。これは、istringstreamがoperator>>を使用して。に解析できないためにコンパイルされませんA

適切なテンプレートの特殊化を使用するにはどうすればよいですか?

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

c++ - (単純な?) C++ の部分的なテンプレートの特殊化を理解する

注:これは問題の再投稿のようです: C++ - そのメソッドの部分的な仕様でテンプレート化されたクラス メソッドをオーバーロードする

C++ テンプレートの特殊化で発生している問題を単純なケースに要約しました。

これは単純な 2 パラメーターのテンプレート クラスで構成されており、ここで特化しThingたいと思います。Thing<A,B>::doSomething()B=int

残念ながら、g++エラーで終了します:

コンパイラはclang++もう少し冗長ですが、同じ問題があります。

Thing関数の部分的なテンプレートの特殊化は許可されていないことを読んで理解しましたが、この場合、クラスを部分的に特殊化していると思いました。

何か案は?

私がやったこと:受け入れられた回答によって提供されたリンクから決定される回避策:

0 投票する
4 に答える
1948 参照

c++ - C++での再帰的なテンプレートのインスタンス化の排除

何かを行う関数を作成するために、さまざまな場所(ファイルスコープ)で呼び出すことができるマクロを定義したいと思います。(以下の例では、関数はメッセージを出力するだけですが、もちろん、私の本当の目的は他の便利なことを行うことです。)課題は、「マネージャー」関数が必要なことです(私の例では、main())マクロ呼び出しに依存するコードなしで(もちろん、マクロ呼び出し自体を除いて)、何らかの方法でそれらすべてを(任意の順序で)呼び出すことに成功します。つまり、ファイルが書き込まれると、別のプログラマーがさまざまな場所にいくつかの新しいマクロ呼び出しを挿入したり、既存の呼び出しの一部を削除したりできるようになり、コードはそれ以上変更しなくても機能します。これは静的オブジェクトを使用して実行できることはわかっていますが、別のアプローチを検討したいと思います。テンプレートのトリックと、__LINE__単調に増加しているという事実を使用します。

このプリント

予想通り。

このソリューションにはいくつかの欠点があります。

  1. REGISTER同じ行で2回呼び出すことはできません。
  2. #lineで遊んだら壊れます。
  3. のすべての呼び出しの後にマネージャーを配置する必要がありREGISTERます。
  4. 再帰的なインスタンス化により、コンパイル時間が増加します。
  5. の「ダミー」インスタンス化fがすべてインライン化されていない限り、実行時のコールスタックの深さは、マネージャ間START_REGISTRATION;および f<__LINE__>();マネージャ内の行数と同じになります。
  6. コードの膨張:の「ダミー」のインスタンス化fがすべてインライン化されていない限り、インスタンス化の数も同様に多くなります。
  7. 過度のインスタンス化再帰の深さは、コンパイラーの制限(私のシステムではデフォルトで500)に達する可能性があります。

問題1-4私は本当に気にしません。問題5は、各関数が前の関数へのポインターを返すようにし、マネージャーがこれらのポインターを使用して関数を相互に呼び出すのではなく、関数を繰り返し呼び出すようにすることで解決できます。問題6は、の呼び出しごとに計算できる同様のクラステンプレート構造を作成することで解消できます。REGISTER前回の呼び出しでインスタンス化された関数。したがって、実際に何かを実行する関数のみをインスタンス化します。その後、過剰なインスタンス化は関数テンプレートからクラステンプレートにシフトされますが、クラスのインスタンス化はコンパイラに負担をかけるだけです。コード生成はトリガーされません。ですから、私の本当の関心事は問題7です。問題は、コンパイラーが再帰的ではなく反復的にインスタンス化を行うように、物事を再構築する方法があるかどうかです。私はまた、(静的オブジェクトを含むものを除いて)さまざまなアプローチを完全に受け入れています。簡単な解決策の1つは、マネージャーの直前にすべての登録をグループ化することです(またはSTOP_REGISTRATION登録のブロックを終了するマクロ)が、それは私の目的の重要な部分を無効にします(それを定義するコードの隣にあるものを登録します)。

編集: いくつかの興味深い提案がありましたが、私が達成したいことに関して自分自身を明確にしていなかったのではないかと思います。私は2つのことに本当に興味があります:提起された問題の解決(つまり、静力学なし、登録ごとの単一行、登録の追加/削除時の追加の変更なし、そして私はそう言うことを怠ったが、標準のC++のみ---したがって、ブーストなし)。以下のコメントで述べたように、私の興味は本質的により理論的です。私はいくつかの新しいテクニックを学びたいと思っています。したがって、再帰を排除する(または少なくとも減らす)か、上記の制約を満たす別のアプローチを見つけるように、物事を再構築することに本当に焦点を当てたいと思います。

編集2: MSalterのソリューションは大きな前進です。最初は、すべての登録にそれまでの行の全費用がかかると思っていましたが、もちろん関数は1回しかインスタンス化できないことに気付きました。したがって、インスタンス化に関しては、線形検索と同じ価格を支払いますが、再帰の深さは対数になります。私がそれに近づいたら、問題5〜7を排除する完全な解決策を投稿します。ただし、それでも一定の再帰の深さで実行できるかどうかを確認するのは良いことですが、インスタンス化の数は呼び出しの数に比例します(ブーストソリューション)。

編集3: これが完全な解決策です。

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

c++ - コードの複製とテンプレートの特殊化 (特殊化された関数の戻り値の型が異なる場合)

D<N>N の値に応じて異なる型を返すメソッド (この場合は operator()) を使用して、テンプレート化されたクラスを作成しています。

2 つの別個のクラス宣言を作成することによってのみ、これを機能させることができましたが、これには多くのコードの重複という代償が伴いました。また、共通のものをスローする共通の基本クラスを作成しようとしましたが、コンストラクターを正しく継承させることができず、それがどれほど慣用的であるかもわかりません...

コードの見栄えを良くするにはどうすればよいですか?

0 投票する
5 に答える
2219 参照

c++ - C ++でIteratorを値型で特殊化するにはどうすればよいですか?

Iteratorテンプレートパラメータをそのパラメータで特殊化することは可能value_typeですか?

次のプロトタイプの関数があります。

InputIterator::value_typeそして、もしそうなら特別に扱いたいSomeSpecificType.

0 投票する
1 に答える
179 参照

c++ - c++template仕様とオーバーロードの解決

関数テンプレートを特殊化しない理由を読み、少し実験した後、興味深いものを見つけました。ここにmain.cxxがあります:

興味深いのは、宣言部分にコメントを付けたままにすると、動作は記事に記載されているとおりです。つまり、int *バージョンの定義がその定義の前にあり、その逆の場合はT*バージョンが使用されます。ただし、宣言ブロックのコメントを解除すると、定義または宣言で使用する順序に関係なく、int*バージョンのみが呼び出されます。私の質問は、この宣言がどのように決議に影響を与えるようになるのかということです。

何か案は?x86_64-redhat-linuxでg++4.2.2を使用しています

編集:AProgrammerの答えを見た後、この質問を単純化してください

0 投票する
3 に答える
2593 参照

c++ - C++テンプレートの部分的な特殊化の質問

次のコードでコンパイル時に問題が発生しています。

エラーメッセージは次のとおりです(「ここ」とマークされた行):

(もちろん、私stdからのベクトルを含めました!)。なにか提案を?私はしばらくそれをいじりましたが、私はいくつかの助けを使うことができるようになりました:-)私は最初のテンプレート宣言を部分的に特殊化して、実際のタイプに応じてコンパイラスイッチの実装を持たせる必要がありますコンテナC(セット用にis_in、ベクトル用に1つ、範囲用に1つ、毎回異なるアルゴリズムがあります)。

ありがとう!

0 投票する
4 に答える
195 参照

c++ - C ++でクラステンプレートを完全に特殊化するときに、同じメンバーを定義する必要がないのはなぜですか?

次のコンパイルが行われていることに非常に驚いています。

なぜこれが許可されるのですか?class SomeCls<int>メソッドを必要としないのは間違っているようvoid UseT(T t)です。私はここで専門分野を見逃していると確信しています(私はC ++の専門家ではありません)。誰かが私を教えてくれませんか?

0 投票する
3 に答える
1985 参照

c++ - C++ での明示的な特殊化

Primer C++ > Adventures in Functions > Templates > Explicit Specialization を読んでいます。

Explicit Specialization の理由/用途を示すために、ケースが示されています。任意の型 (int、double、struct など) を交換できる swap テンプレート関数を検討してください (コードは明らかだと思うので、ここに記述する必要はありません)。

ただし、特定の構造体 (ジョブと呼ばれる) の 2 つのメンバーのみを交換し、残りのメンバーはそのままにしておく必要があります。別の定義が必要になるため、明示的な専門化を作成する必要があります。

同じセクションに次のステートメントがあります。「特殊化は通常のテンプレートをオーバーライドし、非テンプレート関数は両方をオーバーライドします。」その使用のために(通常の)関数を作成しないのはなぜですか?次に、通常の/非テンプレートがテンプレートをオーバーライドしますか?

私の解決策が正しい場合、明示的な特殊化の良い例は何ですか?

0 投票する
3 に答える
12970 参照

c++ - 空のパラメーター パックのテンプレートの特殊化

リスト内の最大数を決定するためにそれ自体を呼び出す可変個引数テンプレート関数があります (テンプレート化された引数によって構成されます)。パラメータ パックが空の場合に特殊化しようとしているので、リストの先頭にある番号を返すことができますが、その方法がわかりません。可変個引数テンプレートとテンプレートの特殊化に慣れてきたばかりですが、これまでのところ次のとおりです。

ただし、これにより次のエラーが発生します。

私もこれを試してみましたが、それが機能するかどうかを確認するためです (ただし、0 未満の数値を返すことができないように、リストに数値 0 をランダムに導入します)。

ただし、上記のエラーに加えて、次のエラーが発生します。

では、これを機能させるにはどうすればよいですか?

-std=c++0xフラグ付きで g++ 4.5.2 を使用しています。