【问题标题】:Force template parameter class to inherit from another templated class with partially fulfilled parameters强制模板参数类从另一个具有部分满足参数的模板类继承
【发布时间】:2016-04-19 08:15:15
【问题描述】:

所以我有以下两个类:

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 classes 以验证其 State-derived 模板参数类实际上是从 State 派生的

【问题讨论】:

标签: c++ templates c++11 inheritance template-inheritance


【解决方案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 ...
};

【讨论】:

    【解决方案2】:

    这符合您的需要吗?

    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

    【讨论】:

      猜你喜欢
      • 2014-07-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-05-12
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多