代码之家  ›  专栏  ›  技术社区  ›  Dmitriy

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

  •  6
  • Dmitriy  · 技术社区  · 15 年前

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

    //.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 回复  |  直到 15 年前
        1
  •  6
  •   vitaut    15 年前

    专门化应该针对同一个类而不是子类,也应该针对类主体之外的类:

    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
  •  5
  •   Community Mohan Dere    9 年前

    如何更正编译错误?

    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 . 如果没有,我的作者是无用的…)