How to create specialization for a single method in a templated class in C++?

点点圈 提交于 2019-12-06 09:20:45

问题


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

I have a templated class:

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 that class to which a char is provided as template parameter, I want function dosome() to behave in a totally different way. But I just want that function to behave differently, everything else must still act the same.

I tried typing:

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

But the compiler tells me that I am 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 questions I saw people creating totally different specialization of the entire class. But I only want a specialization of a single method.


回答1:


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

// Header

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 header

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

or using alternate notation

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



回答2:


One option would be tag dispatching:

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 one 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 yet another one is to move that single function to a base class that you can specialize:

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


来源:https://stackoverflow.com/questions/18701788/how-to-create-specialization-for-a-single-method-in-a-templated-class-in-c

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!