【问题标题】:std::reference_wrapper v.s. int&std::reference_wrapper 与整数&
【发布时间】:2021-03-20 00:14:14
【问题描述】:

我正在尝试使用以下 sn-p 的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,这并不奇怪。

但是,如果我只是将auto 用于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&amp;。然后我有一些问题:

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

谢谢!!

【问题讨论】:

    标签: c++ c++11 reference-wrapper


    【解决方案1】:
    1. 我认为 std::ref 给了我们 std::reference_wrapper 而不是 &?

    这不是问题,但你想的没错。

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

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

    行为上的区别在于,当您分配引用时,您修改了引用的对象,而当您分配引用包装器时,您重新绑定包装器以引用另一个对象,而不是修改引用的对象。

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

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

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

    【讨论】:

    • 感谢@eerorika 解释差异!然后剩下的跟进:有充分的理由为什么在std::make_tuple 之后,引用包装器默认成为一个简单的引用(如您在 2 中指出的)。
    猜你喜欢
    • 2016-01-23
    • 1970-01-01
    • 1970-01-01
    • 2020-02-09
    • 2015-07-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多