web-dev-qa-db-ja.com

C ++テンプレートとダックタイピングの関係は何ですか?

私にとって、C++テンプレートはダックタイピングのアイデアを使用していましたが、これは正しいですか?テンプレートクラスまたはメソッドで参照されるすべてのジェネリック型がダック型であることを意味しますか?

43
Thomson

私にとって、C++テンプレートはダックタイピングのアイデアを使用していましたが、これは正しいですか?

いいえ、C++テンプレートはジェネリックコードの実装に使用されます。つまり、複数のタイプで機能するコードがある場合は、タイプごとにコードを複製する必要はありません。 std::vectorstd::listのようなものは、これが実際に行われている明らかな例です。 C++テンプレート 悪用されています 他のことをすることになりましたが、汎用性が本来の意図でした。

テンプレートクラスまたはメソッドで参照されるすべてのジェネリック型がダック型であることを意味しますか?

いいえ、C++の他のすべての型と同じように「通常の」型です。テンプレートが実際にインスタンス化されるまで、それらはわかりません。

ただし、テンプレートを使用して何かを実装することができますlikeダックタイピング。イテレータはその一例です。この関数について考えてみましょう。

template<class InputIterator, class OutputIterator>
    OutputIterator copy(InputIterator first, InputIterator last,
                        OutputIterator result)
{
    while (first!=last) *result++ = *first++;
    return result;
}

copy関数は、不等式演算子、間接参照演算子、および接尾辞インクリメント演算子を実装すると同時に、引数任意のタイプを受け入れることができることに注意してください。これはおそらく、C++で得られるのと同じくらいダックタイピングに近いものです。

13
In silico

私にとって、C++テンプレートはダックタイピングのコンパイル時バージョンです。コンパイラはコンパイルします。クラスと、Duckに必要なすべてのタイプがある限り、クラスをインスタンス化します。

何かが正しくない場合(コピーコンストラクターがないなど)、コンパイルは失敗します。実際のダックタイピングの対応物は、ダックタイプ以外の関数を呼び出すと失敗します。そして、ここでは実行時に発生します。

74
tgmath

アヒルのタイピングとは、「アヒルのように鳴き、アヒルのように歩くなら、アヒルだ」という意味です。 C++と比較するための、コンピュータサイエンスの正式な定義はありません。

もちろん、C++は(たとえば)Pythonと同じではありませんが、どちらも暗黙的に定義されたインターフェイスの概念を持っています。 Python関数の引数として使用されるオブジェクトに必要なインターフェイスは、関数がそれを使用して実行するものです。C++テンプレート引数として使用される型に必要なインターフェイスは、テンプレートがそのオブジェクトを使用して実行するものです。タイプ。それは類似性であり、それがC++テンプレートを評価する根拠です。

さらに、テンプレート引数の推論により、C++では古いオブジェクトを渡すことができ、コンパイラは関数テンプレートをインスタンス化できるかどうかを判断します。

1つの違いは、C++では、引数が偽医療されない場合、コンパイラーオブジェクトであるということです。 Pythonでは、ランタイムオブジェクトのみ(および関数が実際に呼び出された場合、コードに条件文がある場合のみ)。これは、オブジェクト/タイプに要求されるインターフェイスの性質の違いです。C++では、テンプレートで特定の式が有効である必要があるか、または必要ありません。 Pythonでは、必要な有効な式は、以前に必要な式の実行時の値に依存する可能性があります。したがって、Pythonでは、大声でまたは静かに鳴くオブジェクトを要求できます。大声で鳴く場合は、歩く必要もあります。C++では、条件付き_dynamic_cast_でそれを行うことができます。 、ボリュームがコンパイル時定数の場合、テンプレートの特殊化を行うことができますが、静的型付けを使用して、quack_volume()loudを返す場合にのみアヒルが歩く必要があると言うことはできません。そしてもちろん、Pythonでは、必要なインターフェースは実際には「必須」ではないかもしれません-メソッドが存在しない場合の動作は例外をスローすることであり、文書化して保証することが可能かもしれませんそれが発生した場合の呼び出し元の動作。

「ダックタイピング」を定義して、この違いがC++にそれがないことを意味するかどうかはあなた次第です。

14
Steve Jessop

ではない正確に。ダックタイプ(動的タイプスタイル)は、タイプがないため、コンパイル時のタイプエラーが発生することはありません。テンプレートでは、テンプレートをインスタンス化するまでタイプはありません。一度実行すると、変数には異なるタイプがあり、実際にコンパイル時エラーが発生します。

また、アヒルのタイプでは、変数にはタイプがないため、1つの変数がさまざまなタイプのオブジェクトを指すようにすることができます。テンプレートではそれは不可能です—テンプレートをインスタンス化すると、変数には単一の特定のタイプがあります。

ただし、制約が暗黙的であるという点で類似しています。実際に使用される機能のみがチェックされます。たとえば、多形ポインタとは対照的に、実際の型は重要ではありません。

5
eran

はい、一種の-たとえば、タイプXに適切な署名を持つAddRef()Release()、およびQueryInterface()メソッドがある場合、COMとして使用できます。 CComPtrテンプレートクラスを持つオブジェクト。しかし、これは完全なダックタイピングではありません。パラメータの型チェックは引き続き実施されます。

4
sharptooth

いいえ、これは別の概念です。ダックタイピングは、動的に型付けされたコンテナのタイプを見つける方法です。 C++テンプレートは動的に型付けされておらず、特定の型でインスタンス化されます。

2
duedl0r

ウィキペディア この区別をカバーしています

1