2

継承とテンプレートに関して次の問題があります。

class Base {};
class Deriv : public Base {};

template <class T> class X{};

void f(X<Base>& inst) {}

int main()
{
  X<Base> xb;
  f(xb);
  X<Deriv> xd;
  f(xd);
  return 0;
}

X<Base>との関係がないため、プログラムはコンパイルされませんX<Deriv>。それでも、でできることはすべてできるはずだと思いX<Base>ますX<Deriv>f関数本体を新しい関数にコピーする以外にできることはありますvoid g(X<Deriv>& inst)か?

4

5 に答える 5

2

テンプレートを引き続き使用できます。

template<class T>
void f(X<T>& inst) {}

と の両方X<Base>で機能しX<Derived>ます。

コンパイラはコードを複製する可能性がありますが (十分に賢くない場合)、その必要はありません。

于 2012-04-06T15:52:35.147 に答える
1

なぜそれらが関連していると思いますか?次の点を考慮してください。

template<typename T>
class X;

template<>
class X<Base> {
    int x;
};

template<>
class X<Deriv> {
    double d;
};

それらは間違いなく交換可能ではありません。いいえ、これらのクラス間に関係はなく、一方を他方を期待する関数に渡すことはできません。必要なインターフェイスを公開する別の共通の型から両方の型を継承させるようなことをする必要があります。


あなたのコメントに関しては、型特性を使用static_assertして、Java で行うことを行うことができます。

template<typename T>
void f(X<T>& inst) {
    static_assert(std::is_base_of(Base, T)::value, "Template type must subclass Base");

    // body of function...
}
于 2012-04-06T15:51:07.970 に答える
0

場合によります。が の場合を考えてみましょXstd::shared_ptrstd::shared_ptr<Derived>から派生した場合、型の安全性が損なわれstd::shared_ptr<Base>ますが、代わりに暗黙的な値の変換があります。

ただし、 non- への参照渡しを行っているためconst、このような値の変換は直接役に立ちません。

その他の可能性としては、共通インターフェイスからの継承や、関数のテンプレート化などがあります。

于 2012-04-06T15:54:58.697 に答える
0

そのような機能が必要な場合は、あなたが言ったように、タイプまたはオーバーロードでテンプレート化する必要があります。Xあるいは、 のように明示的に特殊化することもできますX<Derived> : X<Base>

于 2012-04-06T15:50:02.077 に答える
0

テンプレートのさまざまなインスタンス化は、インスタンス化するテンプレート引数が関連している場合でも、関連のない型です。つまり、 と の間の関係X<A>X<B>どうであれ、 は に関係AありBません。

何ができるかは、テンプレートが実際に何であるかによって異なります。場合によっては、特定の操作X<Derived>のために を に変換できるように、変換を提供できます。X<Base>別の代替手段は、関数を変更して、から派生したX<T>for を取得できるようにすることです(これは、テンプレートを作成し、SFINAE を使用して、から派生しない s での呼び出しを禁止することで実行できます。繰り返しますが、テンプレートが何であるかに応じて、基になる型へのアクセスを提供できる場合があります。その場合、関数は参照を取ることができます(またはメソッドを使用して)TBaseTBaseBaseshared_ptrunique_ptr.get()

実際にやりたいことの説明がなければ、適切な代替案を提供することはできません。

于 2012-04-06T15:56:46.343 に答える