我有遗留代码,其中使用类似的方法循环遍历顺序容器(此示例中的向量。某些实现使用其他类型的容器)。因此我将其考虑到模板中,因此我可以为任何容器类型重用相同的代码片段。
template<template<class, class> class TContainer, class TObject>
class cycle
{
public:
explicit cycle( TContainer<TObject, std::allocator<TObject>> & container )
: mContainer( container ), index(0) {}
TObject getNext(int numObjectsToCycle)
{ return mContainer[index++ % numObjectsToCycle]; }
private:
TContainer<TObject, std::allocator<TObject>> & mContainer;
int index;
};
然后我的班级有一个循环器来循环我的变量号。
class myClass
{
std::vector<int> numbers;
public:
cycle<vector, int> cycler;
// Is it safe to pass numbers since it is declared first??
myClass() : cycler(numbers) {}
};
然后,我使用下面的代码。:
myObject.cycler.getNext(size);
将矢量“数字”传递给循环器是一种很好的编程习惯吗?有没有更好的方法来实现我的模板?
代码实际上是能够无限循环遍历对象。我的类是从调用成员方法的外部代码调用的,我希望能够只调用getNext(),所以我不必使用索引。
答案 0 :(得分:0)
在标准库中存在另一个“模式”,它是迭代器模式。基本上每个容器类型都实现begin
和end
,它们分别返回第一个元素和过去结束元素的迭代器(始终保证存在)。
这适用于从std::vector
到std::array
的每种容器类型,包括带有std::begin
和std::end
的C样式数组。如果您想循环使用通用容器,例如:
template<typename Container>
void cicle(Container const& c) {
for (auto const& i : c) {
// …
}
}
或者,为了更好地可视化模式:
template<typename Container>
void cicle(Container const& c) {
for (auto it = std::begin(c); it != std::end(c); ++it) {
// …
}
}