Boost logo

Boost Users :

Subject: Re: [Boost-users] [Boost.Range] combine, native range-for, and destructuring
From: Chris Glover (c.d.glover_at_[hidden])
Date: 2018-04-14 22:44:11


On Sat, 14 Apr 2018 at 08:02 John M. Dlugosz via Boost-users <
boost-users_at_[hidden]> 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



Boost-users list run by williamkempf at hotmail.com, kalb at libertysoft.com, bjorn.karlsson at readsoft.com, gregod at cs.rpi.edu, wekempf at cox.net