1

C++ 標準には次のように記載されています。

クラス テンプレートのメンバーまたは名前空間スコープに表示されるメンバー テンプレートの明示的な特殊化宣言では、メンバー テンプレートとその外側のクラス テンプレートの一部は、特殊化されていないままになる場合があります。囲んでいるクラス テンプレートも明示的に特殊化されていません。(C++11 以降では 14.7.3/16、古い標準では 14.7.3/18)

これは、次のことができないことを意味します。

template<typename T>
class foo {
  template<typename U>
  void bar();
};

template<typename T>
template<>
void foo<T>::bar<some_type>(){
}

これに関連する問題を抱えている人々の質問がすでに複数あり、多かれ少なかれ「標準はそう言っている」と答えています。私が本当に理解していないのは、この制限が存在する理由です。

4

2 に答える 2

0

テンプレート関数は、最初に使用されるとき、または特殊化されたときにインスタンス化されます。

部分的な特殊化を行うと、それはまだテンプレート関数であるため、関数をインスタンス化できません。そのため、特殊化を行う場合、コンパイラは、部分的なインスタンス化が既に行われていることを何らかの方法で理解し、それをインスタンス化に一致させる必要があり、これが問題を引き起こす可能性があります。

人々はコメントで、それはあいまいさにつながる可能性があると言いますが、多くのことがあいまいなことにつながる可能性があります. たとえば、オーバーロードされた関数を考えてみてください。どのオーバーロードされた関数を呼び出すかがあいまいな場合、コンパイラはそれについて通知します。この場合も同じです。

于 2016-06-13T11:31:45.497 に答える
0

答えてくれたJohnBに感謝します:

クラスのみの特殊化 (例: T=int) とメンバーのみの特殊化 (例: U=int) がある場合、どの特殊化を使用するかを決定することは不可能です。

skyjpackによる別のポイント:

メンバー関数のないクラスの特殊化が存在する可能性があります。

于 2016-06-13T11:29:09.510 に答える