3

我正在尝试std::reference_wrapper使用以下代码段

int a = 42, b = 52;
std::tuple<std::reference_wrapper<int>> t = std::make_tuple(std::ref(a));

std::get<0>(t) = b;
std::cout << "t[0] = " << std::get<0>(t) << ", a = " << a << ", b = " << b
          << std::endl;

输出是t[0] = 52, a = 42, b = 52,这并不奇怪。

但是,如果我只使用autofor t,即

int a = 42, b = 52;
auto t = std::make_tuple(std::ref(a));

std::get<0>(t) = b;
std::cout << "t[0] = " << std::get<0>(t) << ", a = " << a << ", b = " << b
          << std::endl;

然后我得到了t[0] = 52, a = 52, b = 52

看起来类型变成了int&。然后我有几个问题:

  1. 我想std::ref给我们std::reference_wrapper而不是&
  2. 我应该如何解释的情况&以及为什么它不同于std::reference_wrapper.
  3. 我还注意到,在 的情况下std::reference_wrapperstd::get<0>(t) = 52;不会编译。(虽然在&它的情况下)。错误是“调用类 'std::__1::reference_wrapper' 的私有构造函数”。有人可以更详细地解释一下吗?

谢谢!!

4

1 回答 1

3
  1. 我认为 std::ref 给了我们 std::reference_wrapper 而不是 &?

这不是一个问题,但你认为正确。

  1. 我应该如何解释 & 的情况以及为什么它与 std::reference_wrapper 不同。

std::reference_wrapper参数传递给std::make_tuple时,结果元组将具有引用成员而不是引用包装器。

行为上的差异是因为当您分配引用时,您修改了引用的对象,而当您分配引用包装器时,您重新绑定包装器以引用另一个对象并且不修改引用的对象。

我还注意到,对于 std::reference_wrapper,std::get<0>(t) = 52; 不编译。(而在 & 的情况下确实如此)。错误是“调用类 'std::__1::reference_wrapper' 的私有构造函数”。有人可以更详细地解释一下吗?

std::reference_wrapper没有被引用类型的赋值运算符。它只有另一个引用包装器的赋值运算符。std::reference_wrapper有一个接受左值的隐式转换构造函数,但没有接受右值的构造函数。

这就是为什么您可以分配b哪个是左值,但不能分配 52 哪个是纯右值。这是一件好事,因为临时对象的生命周期不能被引用包装器延长。

于 2020-12-08T16:40:21.343 回答