c++ - ¿Es lógico este comportamiento std:: ref?
c++11 (3)
arg = xx;
El
arg
local ahora se refiere a (se lee como se vincula con)
xx
.
(Y no más se refiere a
j
)
arg += xx;
El
operator T& ()
implícito
operator T& ()
se aplica para coincidir con el argumento del
operator +=
y, por lo tanto, la suma se realiza en el objeto referido, es decir,
j
.
Entonces el comportamiento observado es correcto.
Considera este código:
#include <iostream>
#include <functional>
int xx = 7;
template<class T>
void f1(T arg)
{
arg += xx;
}
template<class T>
void f2(T arg)
{
arg = xx;
}
int main()
{
int j;
j=100;
f1(std::ref(j));
std::cout << j << std::endl;
j=100;
f2(std::ref(j));
std::cout << j << std::endl;
}
Cuando se ejecuta, este código genera
107
100
Hubiera esperado que el segundo valor fuera 7 en lugar de 100.
¿Qué me estoy perdiendo?
Una pequeña modificación a
f2
proporciona la pista:
template<class T>
void f2(T arg)
{
arg.get() = xx;
}
Esto ahora hace lo que esperas.
Esto ha sucedido porque
std::ref
devuelve un objeto
std::reference_wrapper<>
.
El operador de asignación del cual
vuelve a enlazar
el contenedor.
(ver
http://en.cppreference.com/w/cpp/utility/functional/reference_wrapper/operator%3D
)
No realiza una asignación a la referencia envuelta.
En el caso de
f1
, todo funciona como esperaba porque un
std::reference_wrapper<T>
proporciona un operador de conversión a
T&
, que se unirá al lado derecho implícito del
operator+
implícito
operator+
int
s.
reference_wrapper
tiene
operator =
y un constructor no explícito, consulte la
documentation
.
Entonces, incluso si es sorprendente, es el comportamiento normal:
f2
vuelve a vincular el local reference_wrapper a
xx
.