为迭代器实现泛型方法的正确方法

时间:2016-05-27 15:01:47

标签: c++ oop templates virtual-method

假设我想做这样的事情(这只是一般概念的一个例子):

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

在C ++中显然是非法的。

实现同样目标的正确设计是什么?

我知道我可以使用模板类而不是模板化方法,但除非我实现某种类似工厂的方法,否则这不允许类型推导。

另一件事是 - 我应该“盲目地相信”作为模板参数传递的类型是迭代器吗?

根据评论中的要求:

可能还有很多其他(甚至更好)的例子,但这就是我现在想出来的。

让我们设想一个程序,该程序应该在许多不同容器的上下文中对许多不同排序方法的性能进行基准测试。

有一个像SortingMethodTest这样的类,它将未排序的数据保存在许多不同的容器中(如list,regular array和vector等)。我们传递给它的排序方法函子,它继承自本文前面提到的AbstractSortingMethod之类的东西。基准程序如下所示:

遍历所有容器 - &gt; startTimer() - &gt;将给定容器的迭代器传递给排序方法并运行它 - &gt; stopTimer() - &gt;记录时间 - &gt;继续

1 个答案:

答案 0 :(得分:1)

  

遍历所有容器 - &gt; startTimer() - &gt;将给定容器的迭代器传递给排序方法并运行它 - &gt; stopTimer() - &gt;记录时间 - &gt;继续

基于此,您需要模板,而不是多态。您需要一个采用排序算法和一对迭代器的函数模板:

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>());