如何在子类(c ++)中专门化模板方法?

时间:2010-11-14 09:39:34

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

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

// .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类以支持用户定义的类?

2 个答案:

答案 0 :(得分:6)

应该对同一个类进行专门化,不是为了子类而是在类体之外:

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而不是专业化。

答案 1 :(得分:5)

如何更正编译错误?

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

可以写在你的主要内容中:

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

也就是说,恕我直言,比函数调用的累积更清晰(只要你没有进行格式化,C ++输出流很容易使用)。

(当然,我认为MyWriter不仅仅是对std::cout的简单重定向。如果没有,MyWriter就没用了......)