I do not understand where m_i is bound.
m_i bound to the argument of constructor A What is the argument of constructor A ?
In this case, since the factory does not redirect its argument to A (i.e. does not use std::forward<>() ), then what is passed to A is an lvalue. This is due to the fact that a1 is named, and the named objects are lvalues.
The type a1 not relevant for determining whether a1 value of l or a value of r. So even if a1 is of type rvalue-reference for int ( int&& ), as in your program, parameter a1 itself is a named object, and therefore it is an lvalue.
This means that since m_i is of type lvalue-reference for int , m_i can bind (and is really bound) to the factory (lvalue) parameter a1 , which will be destroyed when factory() returns. In other words, you are left with a sagging link.
Attempting to dereference it (as later in your program) causes Undefined Behavior .
However, if your factory() function redirected its arguments to constructor A :
template<class T, class A1, class A2> T* factory(A1&& a1, A2&& a2) { return new T(std::forward<A1>(a1), std::forward<A2>(a2)); }
This would cause a compiler error because the std::forward<>() mechanism would ensure that lvalues ββremain lvalues ββand rvalues ββremain rvalues. Attempting to bind an lvalue-reference to an rvalue is illegal, and therefore calling constructor A would fail.
source share