Это поведение std::ref логично?
рассмотрим этот код:
#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;
}
при выполнении этот код выводит
107
100
Я ожидал бы, что второе значение будет 7, а не 100.
чего мне не хватает?
3 ответа:
небольшая модификация
f2предоставляет подсказку:template<class T> void f2(T arg) { arg.get() = xx; }это сейчас делает то, что вы ожидаете.
это произошло потому, что
std::refвозвращает astd::reference_wrapper<>"объект". Оператор присваивания которого привязывает фантик. (см. http://en.cppreference.com/w/cpp/utility/functional/reference_wrapper/operator%3D)он не присваивает обернутую ссылку.
на
f1случае, все работает, как вы ожидали, потому чтоstd::reference_wrapper<T>предоставляет оператор преобразования кT&, который будет привязан к неявной правой частиints implicitoperator+.
reference_wrapperиoperator =и не явный конструктор, см. документация.так, даже если это удивительно, это нормальное поведение:
f2привязывает к местной reference_wrapperxx.
arg = xx;Local
argтеперь относится к (читается как связывается с)xx. (И больше не относится кj)
arg += xx;подразумевается
operator T& ()применяется для соответствия аргументуoperator +=и, следовательно, добавление выполняется на указанный объект т. е.j.таким образом, наблюдаемое поведение является правильным.