> On 19 Jan 2015, at 18:35, Akim Demaille <a...@lrde.epita.fr> wrote: > >> Le 19 janv. 2015 à 14:28, Hans Aberg <haber...@telia.com> a écrit : >> >> So it may suffice to have move constructors in the class variant. > > Right. With #if around them :)
I succeeded in replacing all copying with move operations in the calc++ example! It is a bit more: 1. In the grammar .yy file, assignments in the actions must be written $$ = std::move(). so it becomes exp: exp "+" exp { $$ = $1 + $3; } | exp "-" exp { $$ = $1 - $3; } | exp "*" exp { $$ = $1 * $3; } | exp "/" exp { $$ = $1 / $3; } | "(" exp ")" { $$ = std::move($2); } | "identifier" { $$ = std::move(driver.variables[$1]); } | "number" { $$ = std::move($1); }; 2. One needs to flip in && and std::move in a number of places in calc++-parser.hh: /// Construct and fill. template <typename T> variant (const T& t) : yytypeid_ (&typeid (T)) { YYASSERT (sizeof (T) <= S); new (yyas_<T> ()) T (t); } template <typename T> variant (T&& t) : yytypeid_ (&typeid (T)) { YYASSERT (sizeof (T) <= S); new (yyas_<T> ()) T (std::move(t)); } // Bug: first does not have &: basic_symbol (typename Base::kind_type t, const Int& v, const location_type& l); basic_symbol (typename Base::kind_type t, Int&& v, const location_type& l); static inline symbol_type make_NUMBER (const Int& v, const location_type& l); static inline symbol_type make_NUMBER (Int&& v, const location_type& l); template <typename Base> calcxx_parser::basic_symbol<Base>::basic_symbol (typename Base::kind_type t, const Int& v, const location_type& l) : Base (t) , value (v) , location (l) {} template <typename Base> calcxx_parser::basic_symbol<Base>::basic_symbol (typename Base::kind_type t, Int&& v, const location_type& l) : Base (t) , value (std::move(v)) , location (l) {} calcxx_parser::symbol_type calcxx_parser::make_NUMBER (const Int& v, const location_type& l) { return symbol_type (token::TOK_NUMBER, v, l); } calcxx_parser::symbol_type calcxx_parser::make_NUMBER (Int&& v, const location_type& l) { return symbol_type (token::TOK_NUMBER, std::move(v), l); }