Here is a complete program:
#include
using std::cout;
using std::endl;
using std::move;
int count {0}; // global for monitoring
class Triple
If copy elision is disabled, both cases consist of 1 copy followed by 3 moves. (Any output of 2 for your code would indicate a compiler bug).
The copy is:
leftand the moves are:
lefta+b from return valueresult from a+bIt would be more illuminating to replace count with an output message saying "in copy constructor" and "in move constructor" . Currently you are not tracking moves at all.
In the pass-by-reference case , all 3 moves can be elided. In the pass-by-value case, 2 of the moves can be elided. The move which cannot be elided is the move from left to the return value.
I don't know the rationale for why this move can't be elided. Maybe it'd be difficult for a compiler to do something like A a = foo( A() ); if A() were elidable all the way up to a.