クラスclsに機能を提供するために、たとえば「追加」、以下は私が決定したタイプです。
struct add
{
add sum(add other) { ... }
};
対。
template<typename Add>
Add sum(Add one, Add two) { ... }
どのアプローチを優先する必要がありますか、最初のアプローチは2番目のアプローチよりも優れており、その逆もありますか?
クラスclsに機能を提供するために、たとえば「追加」、以下は私が決定したタイプです。
struct add
{
add sum(add other) { ... }
};
対。
template<typename Add>
Add sum(Add one, Add two) { ... }
どのアプローチを優先する必要がありますか、最初のアプローチは2番目のアプローチよりも優れており、その逆もありますか?
どちらのアプローチを優先する必要がありますか、最初のアプローチは2番目のアプローチよりもどのような利点があり、その逆はありますか?
質問には簡単な答えはないと思います。これは、ジェネリック対オブジェクト指向プログラミングの戦いに帰着すると思います。
C++ におけるオブジェクト指向プログラミングとジェネリック プログラミングの緊張関係についても参照してください。
あなたの例の間には2つの違いがあります。まず、正しく指摘しているように、2番目の例は関数テンプレートを使用しています。しかし第二に、それはメンバー関数に対して、フリー関数を使用しています。
公正な比較のために、あなたは比較しているべきです:
add sum(add one, add two) { ... }
と:
template<typename Add>
Add sum(Add one, Add two) { ... }
2番目のバリエーションの方が便利な場合もありますが、関数本体をどのように作成するかによって異なります。一般的な方法で記述しても、add
オブジェクトに対して操作を実行できますか?
最初のものは私には意味がありません、またはあなたが何らかの「操作」を実行するためだけにクラスを書くので、それが意味をなさないほど悪いです。クラスは、オブジェクト指向プログラミングでオブジェクトを表すことになっています(または、そのクラステンプレートの場合、テンプレートmeta-programmigでメタ関数として機能できます)。
操作に関しては、オブジェクトを操作する関数は理にかなっています。したがって、2番目のものは理にかなっていますが、型引数の名前を次のように変更します。
template<typename T>
T sum(const T & one, const T & two) { ... }
結局のところ、何でしたAdd
か?
型に依存する決定はいつ行われますか? ランタイムの場合は仮想メソッドを使用する必要があり、コンパイル時の場合は代わりにテンプレートを使用できます (もちろん、型が実行時に固定されていても仮想メソッドを使用できますが、これは効率が低下します)。
実行時に型が固定されている場合は、テンプレートを使用して、使用している型を伝えたり、コンパイラにそれらを見つけて適切なコードを生成させたりすることを回避するためのいくつかのトリックを使用できます。
ただし、C++ ではテンプレート関数の部分的な特殊化は許可されておらず、テンプレート クラスでのみ許可されていることに注意してください。そのため、最大限の柔軟性を得るには、機能をテンプレート構造のメソッドとしてラップする必要がある場合があります (静的メソッドでも問題ありません)。テンプレート クラスのコンパイル時のディスパッチ機構を配置したら、テンプレート関数を追加して、型推定を可能にし、構文を簡素化できます。