2016-01-14 4 views
1

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

template < class Cost > 
class Transformation { 
    public: 
    virtual Cost getCost() = 0; 
}; 

template < class TransfCl, class Cost > 
class State { 
    protected: 
     State(){ 
      static_assert(
       std::is_base_of< Transformation<Cost>, TransfCl >::value, 
       "TransfCl class in State must be derived from Transformation<Cost>" 
      ); 
     } 
    public: 
     virtual void apply(const TransfCl&) = 0; 
}; 

Но хотелось бы, вместо этого, быть в состоянии отказаться от параметра Cost шаблон для State, потому что функциональность State полностью не зависит от Cost. Таким образом, я мог бы создать не-абстрактные классы, используя синтаксис, похожий на этот:

class TransfImpl : public Transformation<int>{ 
    public: int getCost(){ return 0; } 
}; 

class StateImpl : public State<TransfImpl>{ 
    public: 
     StateImpl(){ 
      static_assert(
       std::is_base_of< Transformation, TransfImpl >::value, 
       "TransfImpl must inherit from Transformation<Cost>" 
      ); 
     } 
     void apply(const TransfImpl &){} 
}; 

Я также хотел бы в конце концов цепь это третий класс, который будет использовать State -derived класса в качестве параметра шаблона, но не нужно буду также иметь Transformation -derived и Cost -derived классов по своим параметрам шаблона для проверки того, что его State -derived класса параметра шаблона, на самом деле, полученных из State

+0

То же http://stackoverflow.com/questions/34670375/how-to -enforce-template-parameter-class-to-output-from-super-with-an-anonymous-t – Arunmu

+0

или [std :: is_base_of для классов шаблонов] (http://stackoverflow.com/a/34672753/2684539) – Jarod42

ответ

1

С

template <template <typename...> class C, typename...Ts> 
std::true_type is_template_base_of_impl(const C<Ts...>*); 

template <template <typename...> class C> 
std::false_type is_template_base_of_impl(...); 

template <template <typename...> class C, typename T> 
using is_template_base_of = decltype(is_template_base_of_impl<C>(std::declval<T*>())); 

Вы можете сделать

template <class TransfCl> 
class State { 
protected: 
    static_assert(is_template_base_of<Transformation, TransfCl>::value, 
        "TransfCl class in State must be derived from Transformation<Cost>"); 

    // previous code ... 
}; 
1

ли этот костюм ваших потребностей?

template < class Cost > 
class Transformation { 
public: 
    typedef Cost TransformationCost; 
    virtual Cost getCost() = 0; 
}; 

template < class TransfCl, class Cost = typename TransfCl::TransformationCost> 
class State { 
    static_assert(
       std::is_base_of< Transformation<Cost>, TransfCl >::value, 
       "TransfCl class in State must be derived from Transformation<Cost>" 
      ); 
protected: 
    State(){} 
public: 
    virtual void apply(const TransfCl&) = 0; 
}; 

class TransfImpl : public Transformation<int>{ 
public: 
    int getCost(){ return 0; } 
}; 

class StateImpl : public State<TransfImpl>{ 
public: 
    StateImpl(){} 
    void apply(const TransfImpl &){} 
}; 

ДОБАВЛЕНО: Live Demo