4

C++ では、名前空間とグローバル スコープ以外のスコープでのメンバー テンプレートの特殊化は許可されていないようです (MS VSC++ エラー C3412)。しかし、私にとっては、基本クラスのプライマリ メンバー テンプレートを派生クラスで特殊化することは理にかなっています。これは、派生クラスが行うこと、つまり基本クラスでの特殊化だからです。たとえば、次の例を考えてみましょう。

struct Base
{
  template <class T>
  struct Kind
  {
      typedef T type;
  };
};

struct Derived : public Base
{
  /* Not Allowed */
  using Base::Kind;
  template <>
  struct Kind <float> 
  {
    typedef double type;
  };
};

int main(void)
{
  Base::Kind<float>::type f;    // float type desired
  Derived::Kind<float>::type i; // double type desired but does not work.
}

私の質問は、なぜそれが許可されていないのですか?

4

3 に答える 3

4

あなたがやろうとしていることはわかりますが、あなたはそれを正しく行っていません。これを試して :

struct Base{};
struct Derived{};

// Original definition of Kind
// Will yield an error if Kind is not used properly
template<typename WhatToDo, typename T>
struct Kind
{
};

// definition of Kind for Base selector
template<typename T>
struct Kind<Base, T>
{
  typedef T type;
};

// Here is the inheritance you wanted
template<typename T>
struct Kind<Derived, T> : Kind<Base, T>
{
};

// ... and the specialization for float
template<>
struct Kind<Derived, float>
{
  typedef double type;
};
于 2009-04-30T18:44:49.527 に答える
1

私の質問は、なぜそれが許可されていないのですか?

ドラフトの私のコピーから、次のように上記の制限が課されているようです。

クラス テンプレート、クラス テンプレートのメンバー、またはクラス メンバー テンプレートの明示的な特殊化宣言では、明示的に特殊化されるクラスの名前は simple-template-id になります。

回避策は、囲んでいるクラスを特殊化することです。

于 2009-04-30T18:34:17.900 に答える
1

標準仕様を「無視」して、論理的な議論を試みます。

2 つのクラスがある場合:

class A
{
   struct S { };

};

class B: public A
{
   struct S { };
};

A::S と B::S は 2 つの異なる型です。ロジックをテンプレートの特殊化に拡張すると、派生クラスの内部クラスを介して基本クラスで宣言された内部クラスを特殊化しようとすると、実際には同じ名前 (ただし別の名前付けスコープ) で別の型を定義しようとしています。

于 2009-04-30T19:46:09.550 に答える