How to specialize a template method in a subclass (C ++)?

I am trying to specialize a non-template class template method 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 get an error message:

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

How to extend the MyWriter class to support user-defined classes?

+6
c ++ visual-studio-2008 templates template-specialization
source share
2 answers

Specialization should be performed for the same class not for the subclass, but also outside the body of the class:

 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 do not need a subclass to specialize the template of the original member function.

Also consider overloading instead of specialization.

+6
source share

How to fix 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 to โ€œspecializeโ€ a template function in a derived class, the solution should be (in a derived class):

  • overloads the template function with a normal function for your MyType parameter
  • "import" a template function into the current class (therefore, it will not be hidden during overloading)

What 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 encode what you want to do?

How to extend the MyWriter class to support user-defined classes?

Now, if you use MyWriter as an extensible output stream, I'm not sure if inheritance is the solution. As vitaut already answered his answer ; you must specialize your template function for the (and external) base object.

How to encode even more what you want to do?

How to extend the MyWriter class to support user-defined classes?

A better solution would be to follow a C ++ flow convention, i.e. use functions that are different from others that are not members. In your case, it will be something like:

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

Anyone can "specialize" your output function without the need for inheritance:

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

What can be written in your main form:

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

What is IMHO is clearer than accumulating function calls (until you do the formatting, C ++ output streams are very easy to use).

(of course, I suppose MyWriter will do more than just redirect to std::cout . If not, MyWriter is useless ...)

+5
source share

All Articles