kain88 kain88 - 1 year ago 106
C++ Question

Is there an equivalent to the range-based `enumerate` loop from python in modern C++?

Is there an equivalent to the range-based

loop from python in C++?
I would imagine something like this.

enumerateLoop (auto counter, auto el, container) {
charges.at(counter) = el[0];
aa.at(counter) = el[1];

Can this be done with templates or macros?

I'm aware that I can just use an old school for-loop and iterate until I reach
. But I'm interested how this would be solved using templates or macros.


I played a bit with boost iterators after the hint in the comments. I got another working solution using C++14.

template <typename... T>
auto zip(const T &... containers) -> boost::iterator_range<boost::zip_iterator<
decltype(boost::make_tuple(std::begin(containers)...))>> {
auto zip_begin =
auto zip_end =
return boost::make_iterator_range(zip_begin, zip_end);

template <typename T>
auto enumerate(const T &container) {
return zip(boost::counting_range(0, static_cast<int>(container.size())),


Answer Source

I wrote something for this a while back.

Essentially, you need to wrap an iterator and give it pair semantics.

AFAIK, there's nothing like this built into the language. And I don't think boost has it either. You pretty much have to roll your own.

// Wraps a forward-iterator to produce {value, index} pairs, similar to
// python's enumerate()
template <typename Iterator>
struct EnumerateIterator {
  Iterator current;
  Iterator last;
  size_t index;
  bool atEnd;

  typedef decltype(*std::declval<Iterator>()) IteratorValue;
  typedef pair<IteratorValue const&, size_t> value_type;

    : index(0), atEnd(true) {}

  EnumerateIterator(Iterator begin, Iterator end)
    : current(begin), last(end), index(0) {
    atEnd = current == last;

  EnumerateIterator begin() const {
    return *this;

  EnumerateIterator end() const {
    return EnumerateIterator();

  EnumerateIterator operator++() {
    if (!atEnd) {

      atEnd = current == last;

    return *this;

  value_type operator*() const {
    return {*current, index};

  bool operator==(EnumerateIterator const& rhs) const {
      (atEnd && rhs.atEnd) ||
      (!atEnd && !rhs.atEnd && current == rhs.current && last == rhs.last);

  bool operator!=(EnumerateIterator const& rhs) const {
    return !(*this == rhs);

  explicit operator bool() const {
    return !atEnd;

template<typename Iterable>
EnumerateIterator<decltype(std::declval<Iterable>().begin())> enumerateIterator(Iterable& list) {
  return EnumerateIterator<decltype(std::declval<Iterable>().begin())>(list.begin(), list.end());

template<typename ResultContainer, typename Iterable>
ResultContainer enumerateConstruct(Iterable&& list) {
  ResultContainer res;
  for (auto el : enumerateIterator(list))

  return res;
Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download