return 类型推导与解包引用的混淆
Confusion on return type deduction with unpacking references
以下代码
#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 报告:
error: cannot bind non-const lvalue reference of type 'std::tuple<int&, int&>&' to an rvalue of type 'std::tuple<int&, int&>'
但是,如果我改变它会编译
auto& [x, y] = memrefs(p);
到
auto [x, y] = memrefs(p)
我的问题是为什么? x
和 y
不是引用吗?
decltype(auto) memrefs(Point &p);
是
std::tuple<int&, int&> memrefs(Point &p);
在structured_binding中,
auto& [x, y]
中的 auto&
适用于 “元组”,不适用于 x
、y
.
你不能
std::tuple<int&, int&>& tup = memrefs(p);
但你可以
std::tuple<int&, int&> tup = memrefs(p);
然后x
,y
指的是元组的适当部分。
行
return std::make_tuple(std::ref(p.x), std::ref(p.y));
正在构造 std::tuple<int&, int&>
类型的临时局部变量,returns 将其作为右值。在这种情况下,作为临时变量,可以使用 const 引用 (const std::tuple<int&, int&>&
) 获取它,也可以将其复制到新元组中 (std::tuple<int&, int&>
) .在您的情况下,您正在尝试获取对临时对象的非 const 引用 (std::tuple <int&, int&>&
),这是不允许的。
如您所指,解决方案是将 memrefs
返回的值复制到新值中或使用 const 引用获取它。
以下代码
#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 报告:
error: cannot bind non-const lvalue reference of type 'std::tuple<int&, int&>&' to an rvalue of type 'std::tuple<int&, int&>'
但是,如果我改变它会编译
auto& [x, y] = memrefs(p);
到
auto [x, y] = memrefs(p)
我的问题是为什么? x
和 y
不是引用吗?
decltype(auto) memrefs(Point &p);
是
std::tuple<int&, int&> memrefs(Point &p);
在structured_binding中,
auto& [x, y]
中的 auto&
适用于 “元组”,不适用于 x
、y
.
你不能
std::tuple<int&, int&>& tup = memrefs(p);
但你可以
std::tuple<int&, int&> tup = memrefs(p);
然后x
,y
指的是元组的适当部分。
行
return std::make_tuple(std::ref(p.x), std::ref(p.y));
正在构造 std::tuple<int&, int&>
类型的临时局部变量,returns 将其作为右值。在这种情况下,作为临时变量,可以使用 const 引用 (const std::tuple<int&, int&>&
) 获取它,也可以将其复制到新元组中 (std::tuple<int&, int&>
) .在您的情况下,您正在尝试获取对临时对象的非 const 引用 (std::tuple <int&, int&>&
),这是不允许的。
如您所指,解决方案是将 memrefs
返回的值复制到新值中或使用 const 引用获取它。