【问题标题】:member template specialization and its scope成员模板专业化及其范围
【发布时间】:2010-10-22 22:41:03
【问题描述】:

在我看来,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.
}

我的问题是为什么不允许这样做?

【问题讨论】:

标签: c++ templates scope specialization


【解决方案1】:

我的问题是为什么不允许这样做?

从我的草稿副本看来,以下内容提出了上述限制:

在 类模板、类模板成员或类成员的显式特化声明 模板,明确特化的类的名称应为 simple-template-id。

解决方法是专门化封闭类。

【讨论】:

    【解决方案2】:

    我明白你想要做什么,但你做得不对。试试这个:

    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;
    };
    

    【讨论】:

      【解决方案3】:

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

      如果你有两个班级:

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

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2015-08-01
        • 2013-09-25
        • 2022-01-24
        • 2013-09-24
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多