Consider this code:
#include
#include
int xx = 7;
template
void f1(T arg)
{
arg += xx;
}
template
A small modification to f2
provides the clue:
template<class T>
void f2(T arg)
{
arg.get() = xx;
}
This now does what you expect.
This has happened because std::ref
returns a std::reference_wrapper<>
object. The assignment operator of which rebinds the wrapper.
(see http://en.cppreference.com/w/cpp/utility/functional/reference_wrapper/operator%3D)
It does not make an assignment to the wrapped reference.
In the f1
case, all is working as you expected because a std::reference_wrapper<T>
provides a conversion operator to T&
, which will bind to the implicit right hand side of int
s implicit operator+
.
arg = xx;
Local arg
now refers to (read as binds with) xx
. (And no more refers to j
)
arg += xx;
Implicit operator T& ()
is applied to match the argument of operator +=
and hence addition is performed on referred object i.e. j
.
So the observed behaviour is correct.
reference_wrapper
has operator =
and a non explicit constructor, see documentation.
So, even if it is surprising, it is the normal behaviour:
f2
rebinds the local reference_wrapper to xx
.