Is there a function like std::for_each that directly passes the iterators instead of the result of dereferencing them?
What we have
std::vector<int> ints;
std::for_each(ints.begin(), ints.end(),
[](int i)
{
//how to get the iterator of this element???
}
what I am searching for
for_each_iterator(ints.begin(), ints.end(),
[](const std::vector<int>::const_iterator &i)
{
//we know the iterator here
}
Of course it is fairly trivial to write such a function, but I am asking if there exists a standard solution from std::, std::tr1:: or boost::
You are looking at the wrong level of abstraction. The for_each algorithm applies the function to each of the elements in the range. If you need to operate on the iterators, you should unroll your loop:
for (auto it = ints.begin(); it != ints.end(); ++it ) {
// do something
}
What you are asking for would be trivially implementable, just not that useful in my opinion. Either you control how iterators are updated in the loop (as in the code above) or there is little use for the iterator itself. What do you want to get out of the iterator?
There is no such thing in the Standard library. But it is not that hard to implement it yourself:
template<typename It, typename Functor >
void iterate(It begin, It end, Functor && f)
{
while ( begin != end ) { f(begin); ++begin; }
}
And use it as:
iterate(ints.begin(), ints.end(), [](std::vector<int>::iterator it)
{
//use it
});
Or use manual loop.
I can only think of how using a wrapper for iterators, I can't think of a way using only standard algorithms, so you still have to write some auxiliary code. Example:
#include <algorithm>
#include <vector>
#include <iostream>
template<typename T>
struct it_wrapper {
it_wrapper(const T& t) : it(t) { }
T operator*() const {
return it;
}
it_wrapper& operator++() {
++it;
return *this;
}
it_wrapper operator++(int) {
it_wrapper old = *this;
++it;
return old;
}
bool operator!=(const it_wrapper& rhs) {
return it != rhs.it;
}
T it;
};
template<typename T>
it_wrapper<T> wrap(const T& t) {
return it_wrapper<T>(t);
}
int main() {
std::vector<int> v { 1, 2, 3, 4 };
std::for_each(wrap(v.begin()), wrap(v.end()), [](decltype(v.begin()) i) {
std::cout << *i << '\n';
});
}
Prints
1
2
3
4
I'm not sure how this is more helpful than just using a for-loop, but you must have your reasons...
Related
Is there an equivalent to the range-based enumerate 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 container.size(). But I'm interested how this would be solved using templates or macros.
EDIT
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 =
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);
}
https://gist.github.com/kain88-de/fef962dc1c15437457a8
Enumeration of multiple variables has been an idiom since C. The only complication is that you can't declare both variables in the initializer of the for loop.
int index;
for (auto p = container.begin(), index = 0; p != container.end(); ++p, ++index)
I don't think it gets any simpler (or more powerful) than that.
There is a pre C++11 solution in boost to this: boost.range.indexed.
Unfortunately it doesn't work with C++11 range based for-loops, only old style verbose loops. However with C++17 it should be become (almost) as easy as in python using structured bindings
Then it should be possible implement something that works like this:
for (auto& [n,x] : enumerate(vec)) x = n;
So, a bit of waiting still ;)
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 {
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;
}
C++17 and structured bindings makes this look OK - certainly better than some ugly mutable lambda with a local [i = 0](Element&) mutable or whatever I've done before admitting that probably not everything should be shoehorned into for_each() et al. - and than other solutions that require a counter with scope outside the for loop.
for (auto [it, end, i] = std::tuple{container.cbegin(), container.cend(), 0};
it != end; ++it, ++i)
{
// something that needs both `it` and `i`ndex
}
You could make this generic, if you use this pattern often enough:
template <typename Container>
auto
its_and_idx(Container&& container)
{
using std::begin, std::end;
return std::tuple{begin(container), end(container), 0};
}
// ...
for (auto [it, end, i] = its_and_idx(foo); it != end; ++it, ++i)
{
// something
}
C++ Standard proposal P2164 proposes to add views::enumerate, which would provide a view of a range giving both reference-to-element and index-of-element to a user iterating it.
We propose a view enumerate whose value type is a struct with 2 members index and value representing respectively the position and value of the elements in the adapted range.
[ . . .]
This feature exists in some form in Python, Rust, Go (backed into the language), and in many C++ libraries: ranges-v3, folly, boost::ranges (indexed).
The existence of this feature or lack thereof is the subject of recurring stackoverflow questions.
Hey, look! We're famous.
You can also more elegantly use the auto ranges available since C++11:
int i = 0;
for (auto& el : container){
charges.at(counter) = el[0];
aa.at(counter) = el[1];
++i;
}
You still have to count the i up by hand, though.
Here's a macro-based solution that probably beats most others on simplicity, compile time, and code generation quality:
#include <iostream>
#define fori(i, ...) if(size_t i = -1) for(__VA_ARGS__) if(i++, true)
int main() {
fori(i, auto const & x : {"hello", "world", "!"}) {
std::cout << i << " " << x << std::endl;
}
}
Result:
$ g++ -o enumerate enumerate.cpp -std=c++11 && ./enumerate
0 hello
1 world
2 !
Tobias Widlund wrote a nice MIT licensed Python style header only enumerate (C++17 though):
GitHub
Blog Post
Really nice to use:
std::vector<int> my_vector {1,3,3,7};
for(auto [i, my_element] : en::enumerate(my_vector))
{
// do stuff
}
Boost::Range supports this as of 1.56.
#include <boost/range/adaptor/indexed.hpp>
#include <boost/assign.hpp>
#include <iterator>
#include <iostream>
#include <vector>
int main(int argc, const char* argv[])
{
using namespace boost::assign;
using namespace boost::adaptors;
std::vector<int> input;
input += 10,20,30,40,50,60,70,80,90;
// for (const auto& element : index(input, 0)) // function version
for (const auto& element : input | indexed(0))
{
std::cout << "Element = " << element.value()
<< " Index = " << element.index()
<< std::endl;
}
return 0;
}
Is there a convenient way to get the index of the current container entry in a C++11 foreach loop, like enumerate in python:
for idx, obj in enumerate(container):
pass
I could imagine an iterator that can also return the index or similar.
Of course I could have a counter, but often iterators don't give guarantees of the order they iterate over a container.
A good implementation of the feature you are requested can be found here:
https://github.com/ignatz/pythonic
The idea behind is, that you build a wrapper struct with a custom iterator that does the counting. Below is a very minimal exemplary implementation to illustrate the idea:
// Distributed under the terms of the GPLv2 or newer
#include <iostream>
#include <vector>
#include <tuple>
// Wrapper class
template <typename T>
class enumerate_impl
{
public:
// The return value of the operator* of the iterator, this
// is what you will get inside of the for loop
struct item
{
size_t index;
typename T::value_type & item;
};
typedef item value_type;
// Custom iterator with minimal interface
struct iterator
{
iterator(typename T::iterator _it, size_t counter=0) :
it(_it), counter(counter)
{}
iterator operator++()
{
return iterator(++it, ++counter);
}
bool operator!=(iterator other)
{
return it != other.it;
}
typename T::iterator::value_type item()
{
return *it;
}
value_type operator*()
{
return value_type{counter, *it};
}
size_t index()
{
return counter;
}
private:
typename T::iterator it;
size_t counter;
};
enumerate_impl(T & t) : container(t) {}
iterator begin()
{
return iterator(container.begin());
}
iterator end()
{
return iterator(container.end());
}
private:
T & container;
};
// A templated free function allows you to create the wrapper class
// conveniently
template <typename T>
enumerate_impl<T> enumerate(T & t)
{
return enumerate_impl<T>(t);
}
int main()
{
std::vector<int> data = {523, 1, 3};
for (auto x : enumerate(data))
{
std::cout << x.index << ": " << x.item << std::endl;
}
}
What about a simple solution like:
int counter=0;
for (auto &val: container)
{
makeStuff(val, counter);
counter++;
}
You could make a bit more "difficult" to add code after the counter by adding a scope:
int counter=0;
for (auto &val: container)
{{
makeStuff(val, counter);
}counter++;}
As #graham.reeds pointed, normal for loop is also a solution, that could be as fast:
int counter=0;
for (auto it=container.begin(); it!=container.end(); ++it, ++counter)
{
makeStuff(val, counter);
}
And finally, a alternative way using algorithm:
int counter = 0;
std::for_each(container.begin(), container.end(), [&counter](int &val){
makeStuff(val, counter++);
});
Note: the order between range loop and normal loop is guaranteed by the standard 6.5.4. Meaning the counter is able to be coherent with the position in the container.
If you have access to Boost its range adaptors can be used like this:
#include <boost/range/adaptor/indexed.hpp>
using namespace boost::adaptors;
for (auto const& elem : container | indexed(0))
{
std::cout << elem.index() << " - " << elem.value() << '\n';
}
Source (where there are also other examples)
C++17 and structured bindings makes this look OK - certainly better than some ugly mutable lambda with a local [i = 0](Element&) mutable or whatever I've done before admitting that probably not everything should be shoehorned into for_each() et al. - and than other solutions that require a counter with scope outside the for loop.
for (auto [it, end, i] = std::tuple{container.cbegin(), container.cend(), 0};
it != end; ++it, ++i)
{
// something that needs both `it` and `i`ndex
}
You could make this generic, if you use this pattern often enough:
template <typename Container>
auto
its_and_idx(Container&& container)
{
using std::begin, std::end;
return std::tuple{begin(container), end(container), 0};
}
// ...
for (auto [it, end, i] = its_and_idx(foo); it != end; ++it, ++i)
{
// something
}
C++ Standard proposal P2164 proposes to add views::enumerate, which would provide a view of a range giving both reference-to-element and index-of-element to a user iterating it.
We propose a view enumerate whose value type is a struct with 2 members index and value representing respectively the position and value of the elements in the adapted range.
[ . . .]
This feature exists in some form in Python, Rust, Go (backed into the language), and in many C++ libraries: ranges-v3, folly, boost::ranges (indexed).
The existence of this feature or lack thereof is the subject of recurring stackoverflow questions.
Hey, look! We're famous.
If you need the index then a traditional for works perfectly well.
for (int idx=0; idx<num; ++idx)
{
// do stuff
}
This question already has answers here:
How to find the index of current object in range-based for loop?
(12 answers)
Closed 9 years ago.
Normal standard method of iterating is this:
for(std::vector<T>::iterator it = v.begin(); it != v.end(); ++it) {
/* std::cout << *it; ... */
}
It involves too much typing and repetating vector variable name.
Is there a way to simplify it like in
for (auto item : vector_var) { /*...*/ }
loop but also having access to index and other functions.
I think of this:
for (auto item : myIterationClass(vector_var)) {
item->index;
item->value;
item->delete();
item->replaceWith(42);
}
It doesn't have to be fast but lean on the code I need to write.
Assuming you'd accept that your loop is slightly changed, it is certainly doable:
for (auto item : myIterationClass(vector_var)) {
item.index();
item.value();
item.erase();
item.replaceWith(42);
}
The idea is to have myIterationClass() be a thin wrapper which return iterators with a fairly custom value. The use of erase() is a bit problematic, though, as you are not supposed to change the container while it is being iterated, i.e., if these are really needed it is necessary to record the elements to be erased and process them later.
Although I don't this this is a good idea, below is a quick demo implementing index() and value(). Implementing replaceWith() would be trivial while implementing anything mutating the length of the sequence could be interesting. Given that the iterator controls the sequence it could probably be done by directly mutating the underlying sequence and adjusting the kept index appropriately. Note that there are also different approach how the iterators are represented. I randomly choose to use a combination of a pointer to the container and an index. If the sequence doesn't add or remove elements, it could also be done using two iterator and computing the index as the difference between the two.
#include <algorithm>
#include <iostream>
#include <vector>
template <typename T>
class wrapped_iterator
{
T* container;
typename T::size_type position;
public:
wrapped_iterator(T* container, typename T::size_type position)
: container(container)
, position(position) {
}
wrapped_iterator<T>& operator*() { return *this; }
wrapped_iterator<T>& operator++() { ++position; return *this; }
wrapped_iterator<T> operator++(int) {
wrapped_iterator<T> rc(*this);
++*this;
return rc;
}
bool operator== (wrapped_iterator<T> const& other) const {
return position == other.position;
}
bool operator!= (wrapped_iterator<T> const& other) const {
return !(*this == other);
}
typename T::size_type index() const { return position; }
typename T::const_reference& value() const { return (*container)[position]; }
};
template <typename T>
class wrapped
{
T* container;
public:
typedef wrapped_iterator<T> iterator;
wrapped(T& container): container(&container) {}
iterator begin() const { return iterator(container, 0u); }
iterator end() const { return iterator(container, container->size()); }
};
template <typename T>
wrapped<T> wrapper(T& container) {
return wrapped<T>(container);
}
int main()
{
std::vector<int> v{ 7, 6, 5, 4, 3, 2, 1 };
for (auto item : wrapper(v)) {
std::cout << "index=" << item.index() << ' '
<< "value=" << item.value() << '\n';
}
}
It's not so bad with auto alone:
for (auto it = std::begin(v), e = std::end(v); it != e; ++it)
{
auto index = std::distance(it, e);
// ...
}
It's maybe not pretty, but it's short enough to type and readable.
Update: Here's a mildly hacky macro "implementation", in the spirit of the range based for loop. (Beware when using with arrays.)
#include <iterator>
#define INDEX_FOR(init, idx, cont, body) \
do \
{ \
auto && __x = (cont); \
for (auto __it = std::begin(__x), \
__end = std::end(__x); \
__it != __end; ++__it) \
{ \
init = *__it; \
auto idx = std::distance(__it, __end);\
body \
} \
} while (false)
Example usage:
#include <iostream>
#include <vector>
int main()
{
std::vector<int> v { 4, -9, 11, 102, 81 };
INDEX_FOR(auto & x, i, v, {
std::cout << "Element " << i << " = " << x << "\n";
});
}
Bjarne Stroustrup in C++11 FAQ says that for (auto item : vector_var) is valid expression. Please, see here: http://www.stroustrup.com/C++11FAQ.html#for
I think this is shorter and easier to use for vectors since auto iteration constructs look somewhat creepy...
int i = 0;
while(i <= myVector.size()) {
myVector[i];
i++;
}
But I prefer maps/lists anyway because used correctly they have alot more performance.
One way using boost is this:
for(auto item:boost::combine(vec, boost::irange(0, vec.size())))
{
auto value = boost::get<0>(item);
auto index = boost::get<1>(item);
...
}
It doesn't give you a way to erase the element, but that should probably be done using the remove-erase idiom.
I'd like to replicate the following with BOOST FOREACH
std::vector<int>::const_iterator i1;
std::vector<int>::const_iterator i2;
for( i1 = v1.begin(), i2 = v2.begin();
i1 < v1.end() && i2 < v2.end();
++i1, ++i2 )
{
doSomething( *i1, *i2 );
}
Iterating over two things simultaneously is called a "zip" (from functional programming), and Boost has a zip iterator:
The zip iterator provides the ability to parallel-iterate over several
controlled sequences simultaneously. A zip iterator is constructed
from a tuple of iterators. Moving the zip iterator moves all the
iterators in parallel. Dereferencing the zip iterator returns a tuple
that contains the results of dereferencing the individual iterators.
Note that it's an iterator, not a range, so to use BOOST_FOREACH you're going to have to stuff two of them into an iterator_range or pair. So it won't be pretty, but with a bit of care you can probably come up with a simple zip_range and write:
BOOST_FOREACH(boost::tuple<int,int> &p, zip_range(v1, v2)) {
doSomething(p.get<0>(), p.get<1>());
}
Or special-case for 2 and use std::pair rather than boost::tuple.
I suppose that since doSomething might have parameters (int&, int&), actually we want a tuple<int&,int&>. Hope it works.
If you use boost, I think it should be as simple as:
#include <boost/foreach.hpp>
#include <boost/range/combine.hpp>
std::vector<int> v1;
std::vector<int> v2;
// iterate over values
int i1, i2;
BOOST_FOREACH(boost::tie(i1, i2), boost::combine(v1, v2))
std::cout << i1+i2 << "\n"; // sums two vectors
// iterate over references
typedef boost::tuple<int&, int&> int_ref_tuple;
BOOST_FOREACH(int_ref_tuple tup, boost::combine(v1, v2))
tup.get<0>() = tup.get<1>(); // assigns one vector to another
the strange part is that boost::combine is not documented. Works for me, anyway.
If you want to use BOOST_FOREACH to iterate two vectors simultenously, as you've done in your sample code, then you've to encapsulate both vectors in a wrapper class which should expose begin and end functions. These functions return custom iterator to be used to iterate over the wrapper which internally will iterate over the two vectors. Doesn't sound good, but that is what you've to do.
This is my first attempt to implement this (minimal implementation just to demonstrate the basic idea):
template<typename T>
struct wrapper
{
struct iterator
{
typedef typename std::vector<T>::iterator It;
It it1, it2;
iterator(It it1, It it2) : it1(it1), it2(it2) {}
iterator & operator++()
{
++it1; ++it2; return *this;
}
iterator & operator *()
{
return *this;
}
bool operator == (const iterator &other)
{
return !(*this != other);
}
bool operator != (const iterator &other)
{
return it1 != other.it1 && it2 != other.it2;
}
};
iterator begin_, end_;
wrapper(std::vector<T> &v1, std::vector<T> &v2)
: begin_(v1.begin(), v2.begin()),end_(v1.end(), v2.end())
{
}
wrapper(const wrapper & other) : begin_(other.begin_), end_(other.end_) {}
iterator begin()
{
return begin_;
}
iterator end()
{
return end_;
}
};
And the following is the test code. Since it's using usual for loop, because ideone has not installed for boost for C++0x or I'm doing something wrong when including it.
int main() {
std::vector<int> v1 = {1,2,3,4,5,6};
std::vector<int> v2 = {11,12,13,14,15};
wrapper<int> w(v1,v2);
for(wrapper<int>::iterator it = w.begin(); it != w.end(); ++it)
{
std::cout << *it.it1 <<", "<< *it.it2 << std::endl;
}
return 0;
}
Output:
1, 11
2, 12
3, 13
4, 14
5, 15
Demo : http://ideone.com/Hf667
This is good for experimentation and learning purpose only, as I don't claim it to be perfect. There can be lots of improvement. And #Steve already has posted boost's solution.
Thanks to the answer of Steve Jessop and the great comments, I came up to the following solution, so if you find that nice, vote up Steve Jessop answer first. ;)
#include <iostream>
#include <vector>
#include <boost/typeof/typeof.hpp>
#include <boost/typeof/std/vector.hpp>
#include <boost/foreach.hpp>
#include <boost/assign/list_of.hpp>
#include <boost/tuple/tuple.hpp>
#include <boost/iterator/zip_iterator.hpp>
#include <boost/range/iterator_range.hpp>
using namespace boost;
int main(int argc, char **argv) {
std::vector<int> vecFirst = assign::list_of(1)(2)(3)(43)(7)(13);
std::vector<double> vecSecond = assign::list_of(53.45)(-23.545)(0.1574)(1.001)(0.0047)(9.7);
BOOST_AUTO(zipSequence,
make_iterator_range(
make_zip_iterator(make_tuple(vecFirst.begin(), vecSecond.begin())),
make_zip_iterator(make_tuple(vecFirst.end(), vecSecond.end()))
)
);
BOOST_FOREACH( BOOST_TYPEOF(*zipSequence.begin()) each, zipSequence) {
std::cout << "First vector value : " << each.get<0>()
<< " - Second vector value : " << each.get<1>()
<< std::endl;
}
}
I'd like to replicate the following with BOOST FOREACH
std::vector<int>::const_iterator i1;
std::vector<int>::const_iterator i2;
for( i1 = v1.begin(), i2 = v2.begin();
i1 < v1.end() && i2 < v2.end();
++i1, ++i2 )
{
doSomething( *i1, *i2 );
}
Iterating over two things simultaneously is called a "zip" (from functional programming), and Boost has a zip iterator:
The zip iterator provides the ability to parallel-iterate over several
controlled sequences simultaneously. A zip iterator is constructed
from a tuple of iterators. Moving the zip iterator moves all the
iterators in parallel. Dereferencing the zip iterator returns a tuple
that contains the results of dereferencing the individual iterators.
Note that it's an iterator, not a range, so to use BOOST_FOREACH you're going to have to stuff two of them into an iterator_range or pair. So it won't be pretty, but with a bit of care you can probably come up with a simple zip_range and write:
BOOST_FOREACH(boost::tuple<int,int> &p, zip_range(v1, v2)) {
doSomething(p.get<0>(), p.get<1>());
}
Or special-case for 2 and use std::pair rather than boost::tuple.
I suppose that since doSomething might have parameters (int&, int&), actually we want a tuple<int&,int&>. Hope it works.
If you use boost, I think it should be as simple as:
#include <boost/foreach.hpp>
#include <boost/range/combine.hpp>
std::vector<int> v1;
std::vector<int> v2;
// iterate over values
int i1, i2;
BOOST_FOREACH(boost::tie(i1, i2), boost::combine(v1, v2))
std::cout << i1+i2 << "\n"; // sums two vectors
// iterate over references
typedef boost::tuple<int&, int&> int_ref_tuple;
BOOST_FOREACH(int_ref_tuple tup, boost::combine(v1, v2))
tup.get<0>() = tup.get<1>(); // assigns one vector to another
the strange part is that boost::combine is not documented. Works for me, anyway.
If you want to use BOOST_FOREACH to iterate two vectors simultenously, as you've done in your sample code, then you've to encapsulate both vectors in a wrapper class which should expose begin and end functions. These functions return custom iterator to be used to iterate over the wrapper which internally will iterate over the two vectors. Doesn't sound good, but that is what you've to do.
This is my first attempt to implement this (minimal implementation just to demonstrate the basic idea):
template<typename T>
struct wrapper
{
struct iterator
{
typedef typename std::vector<T>::iterator It;
It it1, it2;
iterator(It it1, It it2) : it1(it1), it2(it2) {}
iterator & operator++()
{
++it1; ++it2; return *this;
}
iterator & operator *()
{
return *this;
}
bool operator == (const iterator &other)
{
return !(*this != other);
}
bool operator != (const iterator &other)
{
return it1 != other.it1 && it2 != other.it2;
}
};
iterator begin_, end_;
wrapper(std::vector<T> &v1, std::vector<T> &v2)
: begin_(v1.begin(), v2.begin()),end_(v1.end(), v2.end())
{
}
wrapper(const wrapper & other) : begin_(other.begin_), end_(other.end_) {}
iterator begin()
{
return begin_;
}
iterator end()
{
return end_;
}
};
And the following is the test code. Since it's using usual for loop, because ideone has not installed for boost for C++0x or I'm doing something wrong when including it.
int main() {
std::vector<int> v1 = {1,2,3,4,5,6};
std::vector<int> v2 = {11,12,13,14,15};
wrapper<int> w(v1,v2);
for(wrapper<int>::iterator it = w.begin(); it != w.end(); ++it)
{
std::cout << *it.it1 <<", "<< *it.it2 << std::endl;
}
return 0;
}
Output:
1, 11
2, 12
3, 13
4, 14
5, 15
Demo : http://ideone.com/Hf667
This is good for experimentation and learning purpose only, as I don't claim it to be perfect. There can be lots of improvement. And #Steve already has posted boost's solution.
Thanks to the answer of Steve Jessop and the great comments, I came up to the following solution, so if you find that nice, vote up Steve Jessop answer first. ;)
#include <iostream>
#include <vector>
#include <boost/typeof/typeof.hpp>
#include <boost/typeof/std/vector.hpp>
#include <boost/foreach.hpp>
#include <boost/assign/list_of.hpp>
#include <boost/tuple/tuple.hpp>
#include <boost/iterator/zip_iterator.hpp>
#include <boost/range/iterator_range.hpp>
using namespace boost;
int main(int argc, char **argv) {
std::vector<int> vecFirst = assign::list_of(1)(2)(3)(43)(7)(13);
std::vector<double> vecSecond = assign::list_of(53.45)(-23.545)(0.1574)(1.001)(0.0047)(9.7);
BOOST_AUTO(zipSequence,
make_iterator_range(
make_zip_iterator(make_tuple(vecFirst.begin(), vecSecond.begin())),
make_zip_iterator(make_tuple(vecFirst.end(), vecSecond.end()))
)
);
BOOST_FOREACH( BOOST_TYPEOF(*zipSequence.begin()) each, zipSequence) {
std::cout << "First vector value : " << each.get<0>()
<< " - Second vector value : " << each.get<1>()
<< std::endl;
}
}