On Sat, 14 Apr 2018 at 08:02 John M. Dlugosz via Boost-users <boost-users@lists.boost.org> wrote:
I want to go through two vectors at the same time, and the way to do this is to "zip" the
items from each into a tuple.  boost::combine is a function for that.

     for (auto&[def,residue] : boost::combine(playdef, residues)) {

gives me an error



<snip>


Trying to explore the behavior in pieces, I try:

     for (auto row : boost::combine(playdef, residues)) {
        auto&[def, residue] = row;  // line 1
        row.get<1>() = 17;  // line 2
        residue= 42;  // line 3

Now line2 does work, and I note that assignment goes through and updates the original
`residues` vector.

The destructuring on line 1 does compile now, being on a separate line.
But line 3 gives me an error about not being able to assign to a crazy complicated type.

What's going on?  Is Boost.Range zipped ranges simply not compatible with the native
language features?

Hi John,

I'm not en expert on this library, but I have run into the first of your problems before.

When dereferencing a normal iterator, the iterator returns a reference to the actual object being pointed to. The zip iterator can not do this, instead it returns a tuple of references to the the underlying objects as a temporary.

Consider:

vector<int> i;
vector<float> j;

*boost::range::combine(i, j); // This must return something like tuple<int&, float&>

So, you need to bind whats returned from combine to either a const& or an rvalue ref.

for (auto&& row : boost::combine(playdef, residues))

or

for (auto const& row : boost::combine(playdef, residues))

Even the const will work because it's the tuple that's const, not the objects being referenced. As an aside, this means that zip_iterator is not, and can not be, a "proper" iterator as far as standard C++ is concerned. If I remember correctly, this is one issue that the ranges proposal is trying to fix.

As for the second problem, this looks to me like a bug as the library is not correctly interacting with C++17 structured bindings. This  should not really be a surprise, considering this library is much older than that language feature, but it should be addressed, so log a bug, or have a go at trying to fix it and submit a pull request.

Hope this helps,

-- chris