"Eric" == Eric Niebler
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