あなたが求めていることは不可能です。(またはコンパイラが使用している可能性のある同様の構造)で適切なエントリを生成するためにvtbl
、コンパイラは、基本クラスで具体的にどのエントリが必要になるかを知る必要があります。派生クラスで別の型を返すだけで、基本クラスがそのようにそれについて「知っている」ことを期待することはできません。基本クラスの関数テンプレートの定義を変更する必要があるためです。
(関数テンプレートではなく)クラステンプレートを使用して基本クラスのそのような変更を行う方法の例は、 J_Dの回答に示されていますが、それでも問題の説明と正確には一致しません。を作成し、それを多形的に扱うことができます。Value
C ++テンプレートは、基本的にタイプで「ファンシーパンツを見つけて置換」します。コンパイラが関数テンプレートをインスタンス化すると、タイプ名が置換されたプレーン関数が生成されます。これは、C#またはJavaの「ジェネリック」とは大きく異なることに注意してください。これらは完全に異なり、ランタイムサポートと間接化のレイヤーに依存して同様の効果を実現します。(ただし、この「検索と置換」は、Cプリプロセッサマクロとは異なり、優先順位規則などを尊重することに注意してください:))
あなたが本当にそれについても考えるならば、このパターンは意味がありません。これは、クライアント側では実際にどのように見えるでしょうか?
class Value
{
public:
Value();
//Imagine if this were possible...
template <class T>;
virtual T getValue() = 0;
virtual void setValue(T val) = 0;
}
class IntValue : public Value
{
public:
IntValue();
int getValue() {return _val};
void setValue(int val) {_val = val};
private:
int _val;
}
class FloatValue : public Value
{
public:
FloatValue();
float getValue() {return _val};
void setValue(float val) {_val = val};
private:
float _val;
}
次に、このクラスを使用します。
void example(Value * ptr)
{
//What could you possibly say the type of "bar" is? There's no type that works!
???? bar = ptr->getValue();
delete ptr;
}
int main()
{
example(new IntValue());
example(new FloatValue());
}
そのため、これが許可されたとしても、あまり意味がありません。あなたはいつも常にダウンキャストしvirtual
なければならないでしょう、それはキーワードがとにかく無意味であることを意味するでしょう。