开发者

C++: specifying a base class for a template parameter

开发者 https://www.devze.com 2023-03-03 12:54 出处:网络
I need to design a framework that computes the result of a divide-et-conquer algorithm in parallel. In order to use the framework, the user needs to specify somehow the procedure that implements the \

I need to design a framework that computes the result of a divide-et-conquer algorithm in parallel. In order to use the framework, the user needs to specify somehow the procedure that implements the "divide" phase (a function from T to T), the "conquer" phase (a function from D to D) and T and D themselves.

I've thought it would be nice to define two abstract classes, BaseDivide and BaseConquer, which declares a pure virtual method compute with the right types: that way I have a type which implements a well-defined concept (from the point of view of the framework) with the user-definable function included by means of derivation of the abstract classes.

I've thought to use templates to pass the type开发者_开发技巧s to the framework, so the user doesn't have to instantiate them in order to use the framework, so something like that:

template <typename T, typename D, typename Divide, typename Conquer> 
D compute(T arg);

My problem is that I want that Divide and Conquer to be derived types of BaseDivide and BaseConquer: there is a way to enforce it at compile time? Also: do you think I can achieve a similar result with a cleaner design?


You could create the base classes like this:

struct BaseDivide {
    enum EnumDiv { derivedFromBaseDivide = true };
}

template <typename T, typename D, typename Divide, typename Conquer> 
    static_assert(D::derivedFromBaseDivide);
    D compute(T arg);

What is the purpose of the additional Divide and Conquer template parameters? Are you sure you need them?


Use Boost.EnabelIf to trigger SFINAE when your types don't fulfill your requirement. Checking if T is derived from U is doen with boost::is_base_of :

#include <boost/type_traits/is_base_of.hpp>
#include <boost/enable_if.hpp>

template <typename T, typename D, typename Divide, typename Conquer> 
typename boost::
enable_if_c< boost::is_base_of<BaseDivide,Divide>::value 
          && boost::is_base_of<BaseConquer,Conquer>::value
          ,D
          >::type
compute(T arg);


You don't need to use templates for this purpose. Instead, you can use pointers to BaseDivide and BaseConquer objects, and polymorphism will do the job for you.

0

精彩评论

暂无评论...
验证码 换一张
取 消