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

发布于 2024-10-03 02:43:25 字数 872 浏览 4 评论 0原文

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

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

I'm trying to specialize a template method of non-template class in its subclass:

// .h file

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

// .cpp file

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

But I receive an error:

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

How do I extend MyWriter class to support user defined classes?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

吖咩 2024-10-10 02:43:25

应该对同一个类而不是子类以及类主体之外进行专门化:

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

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

另请考虑 重载而不是专门化。

Specialization should be done for the same class not for a subclass and also outside of the class body:

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

You don't need a subclass to specialize the original member function template.

Also consider overloading instead of specialization.

睡美人的小仙女 2024-10-10 02:43:25

如何纠正你的编译错误?

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 的回答已经回答的那样;您应该将模板化函数专门用于基本对象(以及外部)。

如何更准确地编写您想要做的事情?

如何扩展 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 就没用了...)

How to correct your compilation error?

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

If you want a "specialization" of the templated function in the derived class, the solution is to (in the derived class):

  • overload the templated function with a normal function for your MyType parameter
  • "import" the templated function into the current class (so it won't be hidden by the overload)

Which gives:

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

};

How to code correctly what you want to do?

How do I extend MyWriter class to support user defined classes?

Now, if you are using MyWriter as an extensible output stream, I'm not sure inheritance is the solution. As already answered by vitaut on his answer; you should specialize your templated function for (and outside) the base object.

How to code even more correctly what you want to do?

How do I extend MyWriter class to support user defined classes?

A better solution would be to follow the C++ stream's convention, that is, using non-friend, non-member functions. In your case, it would be something like:

class MyWriter {
public:
};

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

Anyone could then "specialize" your output function without needing inheritance:

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

Which could be written in your main as:

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

Which is, IMHO, quite clearer than an accumulation of function calls (as long as you're not doing formatting, the C++ output streams are SO easy to use).

(of course, I assume MyWriter will do more than a simple redirection to std::cout. If not, MyWriter is useless...)

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文