实现迭代器通用方法的正确方式

Proper way of implementing generic methods for iterators

本文关键字:方式 方法 迭代器 实现      更新时间:2023-10-16

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

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

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

为了实现同样的目标,什么是合适的设计?

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

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

根据评论中的请求:

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

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

有一个类似SortingMethodTest的类,它将未排序的数据保存在许多不同的容器中(如列表、正则数组和向量等)。我们向它传递排序方法函子,它继承了本文前面提到的AbstractSortingMethod。基准程序如下所示:

循环所有容器->startTimer()->将给定容器的迭代器传递给排序方法并运行它->stopTime()->记录时间->继续

在所有容器上循环->startTimer()->将给定容器的迭代器传递给排序方法并运行它->stopTime()->记录时间->继续

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

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