I've now changed my grammars to use my new C++17 skeletons with std::variant and move semantics. So far, it seems to work fine.
As expected, they now contain a lot of "std::move ($n)" expressions. Even though the simple case "$$ = std::move ($1)" is now covered by the default action, most are actually within expressions such as "$$ = make_foo (std::move ($1), std::move ($2))" which is less than perfectly readable ... In the original thread, I wrote: > Hans Åberg wrote: > > > >> Perhaps if it know that $1 expires, it can apply a move assignment. > > > > > > It could do that if $1 is mentioned only once. [...] > > > > I think it would be complicated, so just std::move for now. > > I looked into the code. Just adding std::move seems rather easy, but > finding out if a $n is mentioned several times might be tricky on > the m4 level, might require changes to Bison itself. > > And the question remains what to do then. One possibility would be > an option auto-move or such. If not set, std::move is not inserted; > if set it's always inserted, but Bison warns if $n is mentioned > several times. That's what I've implemented now -- except for the warning (which doesn't seem possible without changes to Bison itself). In fact, rather than a Boolean option, I added a define that's wrapped around every $n access. (Though ATM I can't think of any other function except std::move one might want to use there -- maybe some fancy debugging stuff if Bison's trace mechanism isn't sufficient, or whatever ...) By default it's empty, so it's like before, but one can e.g. add %define api.rhs.access {std::move} to always move from all $n. It's then left to the user to make sure moving is safe. For my style of grammar that's fine -- I prefer to do all nontrivial stuff in helper functions, so it's very rare that any $n is mentioned several times in an action (including mid-rule actions) at all. If it is, one can always work around it, by moving to a temporary first, or "un-moving" (after all, std::move doesn't actually move, just type-cast to a moveable rvalue, so one can make it unmoveable again with no harm done). This seems rather lightweight, both to implement in the skeleton and to use in the grammar file, and helps readability a lot for me. Regards, Frank