The following code
#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;
}
does not compile. Reported by 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&>'
However, it will compile if I change
auto& [x, y] = memrefs(p);
to
auto [x, y] = memrefs(p)
My question is why? Aren't x
and y
references?
decltype(auto) memrefs(Point &p);
is
std::tuple<int&, int&> memrefs(Point &p);
In structured_binding,
auto&
in auto& [x, y]
applies to the "tuple", not to x
, y
.
and you cannot have
std::tuple<int&, int&>& tup = memrefs(p);
but you can have
std::tuple<int&, int&> tup = memrefs(p);
then x
, y
refers to the appropriate part of the tuple.