C++:为模板参数指定基类

发布于 2024-11-05 17:15:12 字数 572 浏览 0 评论 0原文

我需要设计一个框架来并行计算分而治之算法的结果。 为了使用该框架,用户需要以某种方式指定实现“划分”阶段(从 T 到 T 的函数)、“征服”阶段(从 D 到 D 的函数)以及 T 和 D 本身的过程。

我认为定义两个抽象类 BaseDivideBaseConquer 会很好,它们声明一个具有正确类型的纯虚拟方法 compute :这样我就有了一个类型,它实现了一个明确定义的概念(从框架的角度来看),并通过抽象类的派生方式包含了用户可定义的函数。

我想过使用模板将类型传递给框架,因此用户不必实例化它们才能使用框架,所以类似这样的事情:

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

我的问题是我希望派生分而治之BaseDivideBaseConquer 的类型:有办法在编译时强制执行它吗?另外:您认为我可以通过更简洁的设计实现类似的结果吗?

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 types 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?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

很酷不放纵 2024-11-12 17:15:12

您可以像这样创建基类:

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

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

附加的分而治之模板参数的目的是什么?您确定需要它们吗?

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?

り繁华旳梦境 2024-11-12 17:15:12

当您的类型不满足您的要求时,使用 Boost.EnabelIf 触发 SFINAE。
检查 T 是否源自 U 是通过 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);

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);
江挽川 2024-11-12 17:15:12

您不需要为此目的使用模板。相反,您可以使用指向 BaseDivide 和 BaseConquer 对象的指针,多态性将为您完成这项工作。

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文