How to create a specialization for one method in a template class in C ++?

Many questions have been asked, and they are similar to the one I'm going to ask here, but they are not what I think.

I have a template:

namespace app { template <typename T> class MyCLass { public: void dosome(); void doother(); } } /*ns*/ 

And implementations:

 template <typename T> app::MyClass<T>::dosome() {} template <typename T> app::MyClass<T>::doother() {} 

When I have an instance of this class that is provided with char as a template parameter, I want the dosome() function to behave completely differently. But I just want this function to behave differently, everything else should act the same.

I tried typing:

 template<> app::MyCLass<char>::dosome() { } 

But the compiler tells me that I'm trying to create a specialization in a different namespace.

So, when I have a code like this:

 app::MyCLass<int> a; app::MyCLass<char> b; a.dosome(); // This must call the generic template definition b.dosome(); // This must call the specialization a.doother(); // This must call the generic template definition b.doother(); // This must call the generic template definition 

In other matters, I saw people creating a completely different specialization of the whole class. But I need only specialization of one method.

+2
source share
2 answers

You can do what you want: http://ideone.com/oKTFPC

// Title

 namespace My { template <typename T> class MyClass { public: void dosome(); void doother(); }; template <typename T> void MyClass<T>::dosome() {} template <typename T> void MyClass<T>::doother() {} template<> void MyClass<char>::dosome(); } 

// cpp or in the header

 template<> void My::MyClass<char>::dosome() { std::cout << "specialization" << std::endl; } 

or using alternative notation

 namespace My { template<> void MyClass<char>::dosome() { std::cout << "specialization" << std::endl; } } 
+2
source

One option is to send tags:

 template <typename T> class MyClass { public: void dosome() { dosome_impl( T() ); } private: void dosome_impl(char) { /* char stuff */ } template<typename U> void dosome_impl(U) { /* usual stuff */ } }; 

Another is enable_if idiom:

 #include <type_traits> template <typename T> class MyClass { public: template<typename U = T> typename std::enable_if<std::is_same<U,char>::value>::type dosome() { /* char stuff */ } template<typename U = T> typename std::enable_if<!std::is_same<U,char>::value>::type dosome() { /* normal stuff */ } }; 

And one more thing is to move this single function to the base class, which you can allocate:

 template <typename T> struct MyClass_base { dosome() { /* usual stuff */ } }; template<> struct MyClass_base<char> { dosome() { /* char stuff */ } }; template <typename T> class MyClass : private MyClass_Base<T> { public: // nothing special here }; 
+2
source

Source: https://habr.com/ru/post/1502562/


All Articles