在现代C++中,有没有相当于python中基于范围的`enumerate`循环?

Max*_*nke 5 c++ enumerate c++14

有没有相当于enumerateC++中python 的基于范围的循环?我会想象这样的事情.

enumerateLoop (auto counter, auto el, container) {
    charges.at(counter) = el[0];
    aa.at(counter) = el[1];
}
Run Code Online (Sandbox Code Playgroud)

可以使用模板或宏来完成吗?

我知道我可以使用旧学校循环并迭代直到我到达container.size().但我很感兴趣如何使用模板或宏来解决这个问题.

编辑

在评论中提示后,我使用了增强迭代器.我使用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 =
    boost::make_zip_iterator(boost::make_tuple(std::begin(containers)...));
  auto zip_end =
    boost::make_zip_iterator(boost::make_tuple(std::end(containers)...));
  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())),
container);
} 
Run Code Online (Sandbox Code Playgroud)

https://gist.github.com/kain88-de/fef962dc1c15437457a8

Omn*_*ity 3

我不久前为此写过一些东西。

本质上,您需要包装一个迭代器并为其赋予配对语义。

AFAIK,语言中没有内置这样的东西。而且我认为 boost 也没有这个功能。你几乎必须自己动手。

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

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

  EnumerateIterator()
    : 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) {
      ++current;
      ++index;

      atEnd = current == last;
    }

    return *this;
  }

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

  bool operator==(EnumerateIterator const& rhs) const {
    return
      (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))
    res.push_back(move(el));

  return res;
}
Run Code Online (Sandbox Code Playgroud)