template <typename T>
void myswap(T a,T b)
{
T temp = a;
a = b;
b = temp;
}
int main()
{
int m(20),n(30);
myswap(ref(m),ref(n));
//m is still 20 and n is still 30
}
为什么m和n的值没有互换?将包含在std::ref
中的值传递给INCREMENT函数会导致原始变量(调用INCREMENT函数的堆栈帧中的变量)中的值更改。或者,std::ref
使用是否受到限制/限制?
答案 0 :(得分:8)
std::ref
(及其关联的std::reference_wrapper
)是为标准库中的特定用例设计的工具,只应用于那些用户;如果你想在你自己的地方使用它,你必须详细了解它并尊重它的作用。
从根本上说,reference_wrapper
更接近指针而不是引用。因此,在交换函数中替换指针,您将看到没有理由认为它实际上会交换:
void myswap(int* a, int* b)
{
int* temp = a;
a = b;
b = temp;
}
答案 1 :(得分:4)
您的代码会创建两个临时std::reference_wrapper
对象并交换它们,因此它们会引用不同的对象。所有这一切都是你交换了两个reference_wrapper
个对象,而不是它们的目标。
如果手动编写函数模板将生成的内容,行为的原因应该是显而易见的:
void myswap(std::reference_wrapper<int> a, std::reference_wrapper<int> b)
{
std::reference_wrapper<int> temp = a;
a = b;
b = a;
}
显然,这不会更改int
个对象,只会更改reference_wrapper
个对象。
如果您要执行的操作是强制myswap
接受您需要致电myswap<int&>(m, n)
的参考,则无法使用reference_wrapper
来模仿。但你应该真正修复myswap
,因为它现在的写法非常无用。
答案 2 :(得分:1)
您的myswap
通过值获取元素。
基本上你在函数的本地范围内交换两个引用(std::reference_wrapper
s)。
他们指出的价值不会发生变化。
template <typename T> void incrementer(T a) { ++a; } int a = 20;
在这种情况下,转换为int&
with:
operator T& () const noexcept { return *_ptr; }
在你的代码中,另一方面:
T temp = a;
将简单地调用复制构造函数,复制构造函数复制基础指针:
reference_wrapper(const reference_wrapper&) noexcept = default;
然后,在下一行中再次复制指针:
reference_wrapper& operator=(const reference_wrapper& x) noexcept = default;