1

I would like to kindly ask you for help with partially specialized class member function definition... let the code explain more:

I have a generic class declaration:

template<typename GEAR_TYPE, typename ENABLER = void>
class PartiallySpecializedClass;

Then I try to partially specialize the class using boost::enable_if

template<typename TYPE_LIST, typename QUERY_TYPE>
struct IsTypeInList
{
    typedef typename boost::mpl::find<TYPE_LIST, QUERY_TYPE>::type TypePos;
    typedef typename boost::mpl::end<TYPE_LIST>::type   Finish;
    typedef typename boost::mpl::not_<boost::is_same<TypePos, Finish> >::type type;
    typedef typename type::value_type value_type;

    static const bool value = type::value;
};

template<typename GEAR_TYPE>
class PartiallySpecializedClass<GEAR_TYPE, typename boost::enable_if<typename IsTypeInList<InvoluteToothTypes, GEAR_TYPE>::type >::type >
{
public:
     void Test( void );
};

If I try to define the method in the class declaration itself, it works fine. But the problems come when I try to define them in separate .cpp file:

template<typename GEAR_TYPE>
void PartiallySpecializedClass< /* WHAT TO PLACE HERE???? */ >::Test( void )
{
}

Is that even possible to define member method of partially specialized class in a separate .cpp file?

Many thanks in advance to anybody who is going to try to help me with this topic. I hope this may help to anybody else having the same nightmare as me :o)

Martin Kopecký
  • 912
  • 5
  • 16
  • template *"in separate .cpp file"*... see [why-can-templates-only-be-implemented-in-the-header-file](http://stackoverflow.com/questions/495021/why-can-templates-only-be-implemented-in-the-header-file) – Jarod42 Dec 30 '15 at 03:04

2 Answers2

3

This example uses std::enable_if from C++11 which is essentially a standardized version of boost::enable_if.

#include <iostream>
#include <type_traits>

// the partial specialization of A is enabled via a template parameter
template<class T, class Enable = void>
struct A {
    void f() {
            std::cout << "generic A::f()" << std::endl;
    }
}; // primary template

template<class T>
struct A<T, typename std::enable_if<std::is_floating_point<T>::value>::type> {
    void f();
}; // specialization for floating point types


template<class T>
void A<T, typename std::enable_if<std::is_floating_point<T>::value>::type>::f() {
    std::cout << "A<for floats>::f()" << std::endl;
}

int main(void) {
    A<int> ai;
    ai.f();
    A<float> af;
    af.f();
}

It yields

generic A::f()
A<for floats>::f()

Notice if you can use C++14 your life becomes even more fancy and pleasure, because there's std::enable_if_t which simplifies the syntax at this point

user3159253
  • 16,836
  • 3
  • 30
  • 56
0

Just to extend the accepted answer, here's how you would write the out of class definition for the generic class:

template <class T, class Enable>
void A<T, Enable>::type>::f()
{
    std::cout << "generic A::f()" << std::endl;
}
Daniel
  • 8,179
  • 6
  • 31
  • 56