2016-05-27 3 views
1

Допустим, я хочу сделать что-то вроде этого (это просто пример общей идеи):Правильный способ реализации родовых методов итераторов

class AbstractSortingMethod 
{ 
    public: 
    template<class iterator> 
    virtual void Sort(iterator begin, iterator end) = 0; 
}; 

, который, очевидно, является незаконным в C++.

Какова правильная конструкция для достижения того же?

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

Другое дело - должен ли я просто «слепо доверять», что тип, который передается как аргумент шаблона, является итератором?

По запросу в комментариях:

Есть, вероятно, многие другие (возможно, даже лучше) примеры, но это то, что я придумал сейчас.

Представьте себе программу, которая должна оценивать производительность многих различных методов сортировки в контексте множества различных контейнеров.

Существует класс, подобный SortingMethodTest, который содержит несортированные данные во многих разных контейнерах (например, список, обычный массив и вектор и т. Д.). Мы передаем ему функтор метода сортировки, который наследуется от чего-то вроде AbstractSortingMethod, упомянутого ранее в этом сообщении. Эталон процедура будет выглядеть следующим образом:

цикл по всем контейнерам -> StartTimer() -> передать итераторы данного контейнера метод сортировки и запустить его -> StopTimer() -> время записи -> продолжить

+4

Зачем вам полипрофильное поведение здесь? Почему бы не использовать политику? – SergeyA

+0

Не могли бы вы привести пример того, как это будет использоваться? – wally

+0

«Какой правильный дизайн для достижения того же?» - чего вы на самом деле хотите достичь?Для абстрактного метода сортировки потребуется динамический вывод типа, что может затруднить работу программы. –

ответ

1

цикл по всем контейнерам -> StartTimer() -> передать итераторы данного контейнера метод сортировки и запустить его -> StopTimer() -> время записи -> продолжить

Исходя из этого, вы хотите шаблоны, а не полиморфизм. Вы хотите, шаблон функции, которая принимает алгоритм сортировки и пару итераторов:

template <class Algorithm, class Range> 
void time_sort(Algorithm algo, Range&& range) 
{ 
    using std::begin; 
    using std::end; 

    // start timer 
    algo(begin(first), end(last)); 
    // stop timer 
    // do stuff with the difference 
} 

А потом вы просто написать кучу разных функциональных объектов, которые реализуют различные виды, которые вы хотите время. В стандартной версии библиотеки это будет что-то вроде:

struct StdSort { 
    template <class Iterator> 
    void operator()(Iterator first, Iterator last) { 
     std::sort(first, last); 
    } 
}; 

, а затем вы будете использовать этот шаблон функции, как:

time_it(StdSort{}, gimme_vector<int>()); 
time_it(StdSort{}, gimme_list<Foo>()); 

Если вы хотите протестировать новые алгоритмы сортировки, просто создать новые типы :

struct MergeSort { 
    template <class Iterator> 
    void operator()(Iterator first, Iterator last) { 
     // ... 
    } 
}; 

struct StackOverflowSort { 
    template <class Iterator> 
    void operator()(Iterator first, Iterator last) { 
     // see xkcd 1185 
    } 
}; 

И передать это как первый аргумент. Промыть и повторить.

time_sort(MergeSort{}, gimme_vector<int>()); 
time_sort(StackOverflowSort{}, gimme_list<Foo>()); 
+0

Спасибо, что нашли время, чтобы написать такой сложный ответ. Это похоже на «истинный C++ способ сделать это». Это похоже на анти-шаблон для меня (ООП-мудрый), но я думаю, это не поможет. – user2521472

+0

@ user2521472 ООП - это почти всегда анти-шаблон. –

Смежные вопросы