C ++: указание базового класса для параметра шаблона - PullRequest
6 голосов
/ 04 мая 2011

Мне нужно спроектировать структуру, которая вычисляет результат алгоритма «разделяй и властвуй» параллельно.Чтобы использовать структуру, пользователь должен каким-то образом указать процедуру, которая реализует фазу «деления» (функция от T до T), фазу «завоевания» (функцию от D до D) и сами T и D.

Я подумал, что было бы неплохо определить два абстрактных класса, BaseDivide и BaseConquer, которые объявляют чистый виртуальный метод compute с правильными типами: таким образом, у меня есть тип, который реализуетчетко определенная концепция (с точки зрения фреймворка) с определяемой пользователем функцией, включенной посредством деривации абстрактных классов.

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

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

Моя проблема в том, что я хочу, чтобы Divide и Conquer были производными типами BaseDivide и BaseConquer: есть способ применить его во время компиляции?Кроме того: как вы думаете, я могу достичь аналогичного результата с более чистым дизайном?

Ответы [ 3 ]

3 голосов
/ 04 мая 2011

Вы можете создать базовые классы следующим образом:

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

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

Для чего нужны дополнительные параметры шаблона Divide and Conquer?Вы уверены, что они вам нужны?

2 голосов
/ 05 мая 2011

Используйте 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);
2 голосов
/ 04 мая 2011

Вам не нужно использовать шаблоны для этой цели.Вместо этого вы можете использовать указатели на объекты BaseDivide и BaseConquer, и полиморфизм сделает эту работу за вас.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...