std::ref 和交换功能似乎不能很好地协同工作

std::ref and swap function does not seem to work well together

本文关键字:不能 很好 协同工作 功能 ref 交换 std      更新时间:2023-10-16
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使用是否受到限制?

std::ref(及其相关std::reference_wrapper(是为标准库中非常具体的用例而设计的工具,应该只用于这些用例;如果你想在你自己的地方使用它,你必须详细了解它并尊重它的作用。

从根本上说,reference_wrapper比引用更接近指针。因此,在您的 swap 函数中替换一个指针,您会发现没有理由假设它实际上会交换:

void myswap(int* a, int* b)
{
    int* temp = a;
    a = b;
    b = temp;
}

您的代码创建两个临时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,因为它现在的编写方式毫无用处。

您的myswap获取元素。

实质上,您在函数的本地范围内交换两个引用(std::reference_wrapper s(。

他们指向的值不会改变。


template <typename T> void incrementer(T a) { ++a; } int a = 20;

在这种情况下,有一个转换为int&

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;