Between operator+
and the constructor of ScopeGuardOnExit
, you twice move-construct an object of the lambda type. In Auto() Auto() I deliberately avoided any move-constructions in favor of just storing a reference to the original lambda; if I recall correctly, that was because I had found that GCC had a hard time optimizing away those move-constructions (even though the lambda object doesn't contain any data members except references, which are trivially moveable and thus ought to be easy to optimize away).
However, I've just now tried to construct a test case where scope_exit
's assembly output differs (at -O2
or higher) from Auto
's, and failed to come up with any actual differences; so I think your move-construction-based version is safe in practice.
Between operator+
and the constructor of ScopeGuardOnExit
, you twice move-construct an object of the lambda type. In Auto() I deliberately avoided any move-constructions in favor of just storing a reference to the original lambda; if I recall correctly, that was because I had found that GCC had a hard time optimizing away those move-constructions (even though the lambda object doesn't contain any data members except references, which are trivially moveable and thus ought to be easy to optimize away).
However, I've just now tried to construct a test case where scope_exit
's assembly output differs (at -O2
or higher) from Auto
's, and failed to come up with any actual differences; so I think your move-construction-based version is safe in practice.
Between operator+
and the constructor of ScopeGuardOnExit
, you twice move-construct an object of the lambda type. In Auto() I deliberately avoided any move-constructions in favor of just storing a reference to the original lambda; if I recall correctly, that was because I had found that GCC had a hard time optimizing away those move-constructions (even though the lambda object doesn't contain any data members except references, which are trivially moveable and thus ought to be easy to optimize away).
However, I've just now tried to construct a test case where scope_exit
's assembly output differs (at -O2
or higher) from Auto
's, and failed to come up with any actual differences; so I think your move-construction-based version is safe in practice.
Between operator+
and the constructor of ScopeGuardOnExit
, you twice move-construct an object of the lambda type. In Auto() I deliberately avoided any move-constructions in favor of just storing a reference to the original lambda; if I recall correctly, that was because I had found that GCC had a hard time optimizing away those move-constructions (even though the lambda object doesn't contain any data members except references, which are trivially moveable and thus ought to be easy to optimize away).
However, I've just now tried to construct a test case where scope_exit
's assembly output differs (at -O2
or higher) from Auto
's, and failed to come up with any actual differences; so I think your move-construction-based version is safe in practice.