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

我将“忽略”标准规范并尝试一个合乎逻辑的论点:

如果你有两个类:

class A
{
   struct S { };

};

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

A::S 和 B::S 是两种不同的类型。将逻辑扩展到模板特化,当您尝试通过派生类中的内部类来特化在基类中声明的内部类时,您实际上是在尝试定义具有相同名称(但另一个命名范围)的不同类型。

于 2009-04-30T19:46:09.550 回答