【问题标题】:How-to specialize template method in subclass(c++)?如何在子类(c++)中专门化模板方法?
【发布时间】:2010-11-14 09:39:33
【问题描述】:

我正在尝试在其子类中专门化非模板类的模板方法:

// .h 文件

class MyWriter {
public:
    template<typename T>
    void test(const T & val) {
        std::cout << val << "\n";
    }
};

// .cpp 文件

class MyType {
public:
    MyType(int aa, double dd) : a(aa), d(dd) {}
    int a;
    double d;
};

class MyWriterExt : public MyWriter {
public:
    template<> void test(const MyType &val) {
        test(val.a);
        test(val.d);
    }
};

int main() {
    MyWriterExt w;
    w.test(10);
    w.test(9.999);
    w.test(MyType(15, 0.25));
 return 0;
}

但我收到一个错误:

Error 1 **error C2912**: explicit specialization; 
'void MyWriterExt::test(const MyType &)' is not a specialization of a function 
    template \testtemplate.cpp 30

如何扩展 MyWriter 类以支持用户定义的类?

【问题讨论】:

    标签: c++ visual-studio-2008 templates template-specialization


    【解决方案1】:

    应该为同一个类而不是子类和类主体之外的类进行专门化:

    class MyWriter {
    public:
        template<typename T>
        void test(const T & val) {
            std::cout << val << "\n";
        }
    };
    
    template<>
    void MyWriter::test<MyType>(const MyType & val) {
        test(val.a);
        test(val.d);
    }
    

    您不需要子类来专门化原始成员函数模板。

    还要考虑overloading 而不是专业化。

    【讨论】:

      【解决方案2】:

      如何纠正你的编译错误?

      Error 1 **error C2912**: explicit specialization; 
       'void MyWriterExt::test(const MyType &)' is not a specialization of
           a function template \testtemplate.cpp 30
      

      如果你想在派生类中对模板化函数进行“特化”,解决方案是(在派生类中):

      • 为您的 MyType 参数使用普通函数重载模板化函数
      • 将模板化函数“导入”到当前类中(因此它不会被重载隐藏)

      这给出了:

      class MyWriterExt : public MyWriter {
      public:
      /*
          template<> void test(const MyType &val) {
              test(val.a);
              test(val.d);
          }
      */
          using MyWriter::test ;
          void test(const MyType &val) {
              test(val.a);
              test(val.d);
          }
      
      };
      

      如何正确编码你想做的事?

      如何扩展 MyWriter 类以支持用户定义的类?

      现在,如果您使用 MyWriter 作为可扩展的输出流,我不确定继承是否是解决方案。正如vitaut on his answer 已经回答的那样;您应该为(和外部)基础对象专门化您的模板化函数。

      如何正确编码更多你想做什么?

      如何扩展 MyWriter 类以支持用户定义的类?

      更好的解决方案是遵循 C++ 流的约定,即使用非友元、非成员函数。在你的情况下,它会是这样的:

      class MyWriter {
      public:
      };
      
      template<typename T>
      MyWriter & operator << (MyWriter & writer, const T & val) {
          std::cout << val << "\n";
          return writer ;
      }
      

      然后任何人都可以“专门化”您的输出函数而无需继承:

      MyWriter & operator << (MyWriter & writer, const MyType & val) {
          writer << val.a << val.d ;
          return writer ;
      }
      

      在你的 main 中可以写成:

      int main() {
          MyWriter w;
          w << 10 << 9.999 << MyType(15, 0.25);
       return 0;
      }
      

      恕我直言,这比函数调用的积累要清晰得多(只要您不进行格式化,C++ 输出流就很容易使用)。

      (当然,我认为 MyWriter 将做的不仅仅是简单的重定向到 std::cout。如果不是,MyWriter 没用...)

      【讨论】:

        猜你喜欢
        • 2013-04-09
        • 2015-06-15
        • 1970-01-01
        • 1970-01-01
        • 2014-02-06
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多