Boost logo

Proto :

Subject: Re: [proto] problem with constness of operator return types
From: Thomas Heller (thom.heller_at_[hidden])
Date: 2010-12-02 10:41:35


Eric Niebler wrote:

> On 12/2/2010 6:51 AM, Thomas Heller wrote:
>> Hi,
>>
>> I just encountered a somehow stupid problem. Possibility is high that i
>> missed something.
>>
>> The problem is, that proto's default transform cannot handle op_assign
>> correctly. This is due to the fact that operator OP returns a const proto
>> expression, which turns every value type in proto terminals into a const
>> value.
>
> Actually, it doesn't. See below:

<snip>

You are right ... the problem vanished...
 
> Proto holds children by reference by default, and respects their
> constness. So what problem are you seeing, exactly?
>
> I can guess that in Phoenix, you are seeing this problem because we told
> Proto that in the Phoenix domain, children need to be held by value. In
> this case, the top-level const really is a problem.
>
> What's the right way to fix this?
<snip>

No fix needed.

> I don't actualy believe this is the right fix. Phoenix stores terminals
> by value *by design*. I argue that "t1 += t2" should NOT compile.
> Consider this Phoenix code:
>
> auto t1 = val(9);
> std::for_each(c.begin(), c.end(), t1 += _1);
>
> What's the value of t1 after for_each returns? It's 9! The for_each is
> actually mutating a temporary object. The const stuff catches this error
> for you at compile time. You're forced to write:
>
> int t1 = 9;
> std::for_each(c.begin(), c.end(), ref(t1) += _1);
>
> Now the terminal is held by reference, and it works as expected.
>
> If you think there are legitimate usage scenarios that are busted by
> this const stuff, please let me know.

Sorry about the noise! There were some references missing in the result type
calculation.


Proto list run by eric at boostpro.com