I have legacy code where a similar method is used to cycle through a sequential container (vector in this example. Some implementations use other kinds of containers). So I factored it out into a template so I could reuse the same piece of code for any container type.
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;
};
Then my class has a cycler to cycle through my variable numbers.
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) {}
};
Then, I use the code like below.:
myObject.cycler.getNext(size);
Is it a good programming practice to pass the vector "numbers" to cycler? Is there a better way of implementing my template?
The code really is to be able to infinitely loop through objects. My class is invoked from external code that just calls a member method, and I want to be able to just call getNext() so I wouldn't have to use an index.
In the standard library another "pattern" exists and it's the iterator pattern . Basically every container type implements begin
and end
which returns, respectively, the iterator to the first element and the past-the-end element (which is always guaranteed to exists).
This works for every container type, from std::vector
to std::array
including C-style arrays with std::begin
and std::end
. If you want to loop in a generic container you can do, for example:
template<typename Container>
void cicle(Container const& c) {
for (auto const& i : c) {
// …
}
}
or, to better visualize the pattern:
template<typename Container>
void cicle(Container const& c) {
for (auto it = std::begin(c); it != std::end(c); ++it) {
// …
}
}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.