Pass in the body of the loop as a functor. It gets inlined at compile-time, no performance penalty.
The idea of passing in what varies is ubiquitous in the C++ Standard Library. It is called the strategy pattern.
If you are allowed to use C++11, you can do something like this:
#include <iostream>
#include <set>
#include <vector>
template <typename Container, typename Functor, typename Index = std::size_t>
void for_each_indexed(const Container& c, Functor f, Index index = 0) {
for (const auto& e : c)
f(index++, e);
}
int main() {
using namespace std;
set<char> s{'b', 'a', 'c'};
// indices starting at 1 instead of 0
for_each_indexed(s, [](size_t i, char e) { cout<<i<<''<<e<<'
'; }, 1u);
cout << "-----" << endl;
vector<int> v{77, 88, 99};
// without index
for_each_indexed(v, [](size_t , int e) { cout<<e<<'
'; });
}
This code is not perfect but you get the idea.
In old C++98 it looks like this:
#include <iostream>
#include <vector>
using namespace std;
struct with_index {
void operator()(ostream& out, vector<int>::size_type i, int e) {
out << i << '' << e << '
';
}
};
struct without_index {
void operator()(ostream& out, vector<int>::size_type i, int e) {
out << e << '
';
}
};
template <typename Func>
void writeVector(const vector<int>& v, Func f) {
for (vector<int>::size_type i=0; i<v.size(); ++i) {
f(cout, i, v[i]);
}
}
int main() {
vector<int> v;
v.push_back(77);
v.push_back(88);
v.push_back(99);
writeVector(v, with_index());
cout << "-----" << endl;
writeVector(v, without_index());
return 0;
}
Again, the code is far from perfect but it gives you the idea.
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…