返回类型推论与解包引用的混淆
Posted
技术标签:
【中文标题】返回类型推论与解包引用的混淆【英文标题】:Confusion on return type deduction with unpacking references 【发布时间】:2022-01-21 23:50:50 【问题描述】:以下代码
#include <functional>
#include <tuple>
#include <iostream>
struct Point
int x;
int y;
;
decltype(auto) memrefs(Point &p)
return std::make_tuple(std::ref(p.x), std::ref(p.y));
int main()
Point p;
auto& [x, y] = memrefs(p);
x = 1;
y = 2;
std::cout << p.x << " " << p.y << std::endl;
return 0;
不编译。由 GCC 8.1.0 报告:
错误:无法将'std::tuple
&'类型的非常量左值引用绑定到'std::tuple '类型的右值
但是,如果我改变它会编译
auto& [x, y] = memrefs(p);
到
auto [x, y] = memrefs(p)
我的问题是为什么? x
和 y
不是引用吗?
【问题讨论】:
decltype(auto) memrefs(Point &p)
返回一个临时值,即右值。右值只能绑定const &
,或者在您的第二种情况下复制。
您在寻找std::tie
吗?
感谢您的回复。现在对我来说有点道理。我无法理解当返回单个引用时必须使用 auto& x = getref();
而不是返回多个引用时这一事实。
【参考方案1】:
decltype(auto) memrefs(Point &p);
是
std::tuple<int&, int&> memrefs(Point &p);
在structured_binding,
auto&
in auto& [x, y]
适用于 "tuple",不适用于 x
、y
。
你不能拥有
std::tuple<int&, int&>& tup = memrefs(p);
但你可以拥有
std::tuple<int&, int&> tup = memrefs(p);
那么x
、y
指的是元组的适当部分。
【讨论】:
【参考方案2】:线
return std::make_tuple(std::ref(p.x), std::ref(p.y));
正在构造一个std::tuple<int&, int&>
类型的临时局部变量并将其作为右值返回。在这种情况下,作为一个临时变量,它可以通过 const 引用 (const std::tuple<int&, int&>&
) 获取,也可以复制到新的元组 (std::tuple<int&, int&>
) 中。在您的情况下,您试图获取对临时对象的非 const 引用 (std::tuple <int&, int&>&
),这是不允许的。
您如何指出,解决方案是将memrefs
返回的值复制到一个新值中,或者使用 const 引用获取它。
【讨论】:
我同意你的观点,但是pastebin.com/8p6JY7fb 它打印出 std::tuplestd::make_tuple
处理 std::reference_wrapper
以使用参考。
@Jarod42 所以简而言之,我和int&
是对的?以上是关于返回类型推论与解包引用的混淆的主要内容,如果未能解决你的问题,请参考以下文章