Как определить функцию-член частично специализированного класса шаблона, используя boost::enable_if

Я хотел бы попросить вас помочь с определением частично специализированной функции-члена класса... пусть код объяснит больше:

У меня есть объявление общего класса:

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

Затем я пытаюсь частично специализировать класс, используя 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 );
};

Если я попытаюсь определить метод в самом объявлении класса, он отлично работает. Но проблемы возникают, когда я пытаюсь определить их в отдельном файле .cpp:

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

Возможно ли вообще определить метод-член частично специализированного класса в отдельном файле .cpp?

Заранее большое спасибо всем, кто попытается помочь мне с этой темой. Я надеюсь, что это может помочь кому-то еще, у кого такой же кошмар, как у меня :о)


person Martin Kopecký    schedule 29.12.2015    source источник
comment
шаблон в отдельном файле .cpp... см. почему-шаблоны-могут-быть-только-реализованы-в-заголовочном-файле   -  person Jarod42    schedule 30.12.2015


Ответы (2)


В этом примере используется std::enable_if из C++11, который по сути является стандартизированным версия 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();
}

Это дает

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

Обратите внимание, что если вы можете использовать C++14, ваша жизнь станет еще более красивой и приятной, потому что на этом этапе есть std::enable_if_t, который упрощает синтаксис.

person user3159253    schedule 29.12.2015

Просто чтобы расширить принятый ответ, вот как вы могли бы написать определение вне класса для универсального класса:

template <class T, class Enable>
void A<T, Enable>::type>::f()
{
    std::cout << "generic A::f()" << std::endl;
}
person Daniel    schedule 23.01.2020