web-dev-qa-db-ja.com

関数のオーバーロードと関数テンプレート-C ++

C++の本では、C++で自由にtemplatesを使用しているのに、なぜfunction overloadingを使用するように教えられているのですか?

テンプレートの効果的な(そして正しい)使用法を示す方が良いのではないでしょうか? C++に関するほとんどの本で関数のオーバーロードが教えられているのとは対照的に?

または、一方を他方の代わりに使用する十分な理由はありますか?

24
kushalvm

テンプレートは、異なる可能性のあるタイプに対して同じアクションを実行する場合に有利です。簡単な例:

template <typename T>
T foo(const T& a, const T& b) { return a + b; }

タイプに応じて異なる操作を適用する場合は、オーバーロードを使用できます。

struct Foo{ void foo() const {} };

void foo(int i) { std::cout << "i = " << i << "\n"; }
void foo(const Foo& f) { f.foo(); }

テンプレートとテンプレートの特殊化を使用して上記を実現できますが、そのような特殊化は一般的なケースのいくつかの例外を表す必要があります。

25
juanchopanza

テンプレートはさまざまな数の引数を取ることはできません。オーバーロードはできます。さらに、テンプレートは任意のデータ型を操作できることを示しますが、実際には、テンプレートの大部分、大部分が特殊化(システム内のみ)である場合、これを表すのは無意味です。また、オーバーロードはvirtualにすることができ、テンプレートの特殊化はできません。また、スペシャライゼーションのシグネチャがベースと異なることもありません。

template<typename T> void foo(T& t);
template<> void foo<std::string>(std::string* ptr); // Illegal
void foo(std::string* ptr); // Legal

これは、現在のシステムと比較して、どのような種類の過負荷が発生するかを厳しく制限します。

6
Puppy

多くの異なるデータ型に対して同じ一連の操作を実行する場合は、通常、テンプレートを使用します。

通常、特定のデータセットに対して異なる操作を実行する場合は、関数のオーバーロードを使用します。

多くの異なるデータ型に対して同じ操作セットを実行したい場合のテンプレートの利点は、コンパイラーがコンパイル時に、テンプレート関数を使用する将来作成する可能性のある新しい型を処理できることです。関数オーバーロードを使用する場合、特定の関数に渡したい新しい型を作成するたびに、新しい関数オーバーロードを作成する必要があります。

3
Mike Corcoran

フアンチョパンザの答えへの追加:

関数オーバーロードを使用すると、引数の数を変更することもでき、便利です。

次の宣言を持つ関数がある場合の簡単な例:

void foo(int i, int j);

しかし、最初の引数を0にしてfooを呼び出すことがよくあります。次の関数を書くと、タイピングの手間が省けます。

void foo(int j) {
  foo(0, j);
}
2
Vlad

テンプレートでは、(通常)すべての(サポートされている)タイプで操作を実行するために、同一のsyntaxを使用する必要があります。

関数のオーバーロードも同様に使用されます(または使用する必要があります)が、different構文を使用してさまざまな型の操作を実行できます。つまり、(必須ではありませんが)さまざまな方法で値を表すことができます。 1つの明白な例は、Cライブラリでatanおよびatan2と呼ばれるものです。 atanを使用すると、「ライズ」と「ラン」の比率が渡され、比率が表す角度が返されます。atan2を使用すると、ライズの値を渡して個別に実行します(これはほぼ同じ結果を計算しますが、入力データが少し多いため、より完全な結果も生成できます)。

これらはCでは完全に別個の関数として実装されていますが、最初からC++で記述されている場合、1つと2つのパラメーターの両方にオーバーロードされた単一の名前(例:atan)を使用することは完全に適切です。

double atan(double);           // equivalent to current atan
double atan(double, double);   // equivalent to current atan2

テンプレート(特殊化を除けば、テンプレート自体が提供するものをオーバーライドするだけです)では、このような呼び出し構文に違いはありません。

オーバーロードはさらに制約されます-サポートする特定の型ごとに1つのオーバーロードを提供します(ただし、ポインターまたは参照を取得した場合、派生型もサポートできます)。テンプレートを使用すると、単一のテンプレートを(少なくとも潜在的に)anyタイプに適用できます。

1
Jerry Coffin

したがって、overloadingtemplateはどちらも同じように使用されます。

1行differenceそれらについて:

overloadingは、さまざまな関数がある場合に使用され、SIMILAR操作を実行します。

templateは、さまざまな関数がある場合に使用され、IDENTICAL操作を実行します。

There is very big differnce between "SIMILAR" and "IDENTICAL".

0
Ritik Kamboj