Boost logo

Boost Users :

Subject: Re: [Boost-users] [proto] a question on assignment operators
From: Maurizio Vitale (maurizio.vitale_at_[hidden])
Date: 2009-08-24 17:29:11


>>>>> "Eric" == Eric Niebler <eric_at_[hidden]> writes:

    Eric> (Public response to Maurizio's private follow-up. Hope
    Eric> Maurizio doesn't mind.)

Not a problem. It was private to save people's bandwidth until my revised
explanation was clear enough.

>> The problem I'm having is that expressions built by proto seem to
>> be const, forcing operator= to be const (or at least that's what
>> happens in my example).

    Eric> It's true, Proto's objects have a top-level const
    Eric> qualification. They are, after all, rvalues (temporaries) so
    Eric> they should not be modified.

    Eric> HOWEVER, the const-ness only applies at the top-level. The
    Eric> const-ness of child nodes is preserved. In particular,
    Eric> non-const lvalue terminals are held by reference and remain
    Eric> non-const. Consider:

Ok, but that toplevel constness is what forces operator= to be
const. If I understand you correctly, this is intentional and having a
const operator= unavoidable. It kind looks weird.

    Eric> typedef proto::terminal<int>::type I; I i = {42}; I & refi =
    Eric> proto::left(i+i);

    Eric> The temporary object created by i+i is const, but each i is
    Eric> held by non-const reference, which is what is returned by
    Eric> proto::left.

>> If that's true, then my followup question was whether it is ok to
>> perform the assignment the way I was doing it, casting away
>> const.

    Eric> In short, it shouldn't be necessary. You're using
    Eric> proto::flatten and fusion::fold. Somewhere in there the
    Eric> constness is getting messed up. You should file a bug.

I'm afraid at this point I don't understand enough of the problem in
order to file an useful report with the fusion developers. I probably
wouldn't be able to produce a small fragment exposing the bug and not
involving proto.

I can certainly send them the code as it is, if you think it would be
useful. Is the boost devel mailing list the appropriate place?

    Eric> Proto's fold_tree transform gets the constness correct. See
    Eric> the attached code which is equivalent to yours, but doesn't
    Eric> require any ugly const_cast's.

Thanks for the code. I'll study it later.

>> The other question I had was on what was the reason for
>> explicitely disable assignment operators in grammars. This is
>> something you do in many of your examples

    Eric> I do? Which examples? I don't see it.

lambda.hpp: // Use a grammar to disable Proto's assignment operator overloads.
mixed.cpp: // A grammar which matches all the assignment operators,
vector.cpp: // A grammar which matches all the assignment operators,

>> , but doesn't seem to make a difference in my code (e.g. having
>> an operator= in my expression seems to stop proto from building a
>> larger tree including the '=' anyhow, without needing to disable
>> it explicitly)

    Eric> I'm afraid you've lost me again.

It seems like defining an operator= on extended expressions is all you
need in order to prevent proto from using its own overload. Hence I was
wondering what was the reason for disabling the assignment operators in
the grammar, like done in the examples mentioned above.

Thanks,

  Maurizio


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