2013-12-09 11 views
6

はいつか私のような2つのテンプレート書きたい:なぜC++でテンプレートのオーバーロードが許可されないのですか?

template <typename Type1> 
class A{ 
    ... 
}; 

template <typename Type1, typename Type2> 
class A{ 
    ... 
}; 

をしかし、2つのテンプレートが同じ名前を共有するが、異なるパラメータを持つ持つことは違法であると思われます。私はそれをA_1,A_2のように名づけなければならない。 Functorを実装するときにこれを行うことができれば便利だと思います。

なぜC++はこれを許可していませんか?いくつかの状況で実装するのが難しく、あいまいさがありますか?これはC++のそれ以降のバージョンでサポートされますか?

+7

同じ理由から、C++では同じ名前の2つのクラスが許可されていません。 – Jack

+2

C++ 11バリアントテンプレートの使用http://en.wikipedia.org/wiki/Variadic_template – higuaro

+0

おそらく、デフォルトのテンプレート引数で近似できます。 –

答えて

12

これは非常に便利ですが、あなたの言うように、C++ではこれを直接行うことはできません。しかし、部分的特化でほぼ同じことができます。

はあなたが次の操作を行うことができますよう可変引数テンプレートC++ 11でを使用する場合、これは特に容易である:

template <typename... T> 
struct A; // Declared but not defined 

template <typename T, typename U> 
struct A<T, U> 
{ 
    // definition of the two-parameter case 
}; 

template <typename T> 
struct A<T> 
{ 
    // definition of the one-parameter case 
}; 

事実上、これはあなたが完全に別の種類としてA<T, U>A<T>を持つことができます。より多くのテンプレートパラメータを使用してAをインスタンス化しようとすると、一般的なケースが定義されていないため、コンパイルエラーが発生します(必要ならばstatic_assertを使用して良いエラーメッセージを表示できます)。

デフォルトのテンプレートパラメータ(空のダミー構造体、またはvoidに設定されています)を使用してC++ 03でも同様のことが達成できますが、C++ 11のバージョンははるかに優れたIMOです。

0

単純な(可能な)解決策は、2番目のテンプレート引数のデフォルト値を持つことです。 この方法では、1つのテンプレートのみを実装し、1つのテンプレート引数で呼び出すことができ、デフォルトの秒を使用するか、デフォルトを上書きします。