Search code examples
c++templatesmember-functionsexplicit-specialization

How to specialize member functions based on class template argument


What the question says. In addition, is it possible to do this inline?

Here is a small example just to give an idea...

template<typename T>
class Foo {
 public:
  Foo() :z(0.0) {}

  void do( const Foo<T> &f ) {
    z = f.z;
  }
  // specialize 'do' for Foo<int>, possible inline?

 private:
  T z;
};

Solution

  • You can sort of get this behavior by making the member function a member function template and using SFINAE (substitution failure is not an error). For example:

    template <typename U>
    typename std::enable_if<!std::is_integral<U>::value && 
                            std::is_same<T, U>::value, void>::type
    f(const Foo<U>& x)
    {
    }
    
    template <typename U>
    typename std::enable_if<std::is_integral<U>::value && 
                            std::is_same<T, U>::value, void>::type
    f(const Foo<U>& x)
    {
    }
    

    The is_integral type trait test whether U is an integer type. If it is not, the first is instantiated; if it is, the second is instantiated.

    The is_same type trait tests to ensure T and U are the same type. This is used to ensure that the member function template is not instantiated for any type other than Foo<T>.

    This example makes use of the C++0x <type_traits> library; Boost also has a type traits library that you can use, which works mostly the same.