The commented line in the following snippet does not work as expected:
double a, b;
auto [c, d] = std::make_tuple<double, double&>([&]() -> double { return a; }(),
[&]() -> double& { return b; }());
static_assert(std::is_same_v<double, decltype(c)>);
// static_assert(std::is_same_v<double&, decltype(d)>); // Compile error!
Specifically, I would like to return both an rvalue and an lvalue in a single structured binding declaration. I have tried to declare c
and d
both using auto&
and auto&&
, but none of the approaches worked. Is there a way to achieve the above desired behavior?
std::make_tuple<double, double&>(...)
returns std::tuple<double, double>
, since it applies std::decay
to the template arguments. In any case, you're not supposed to specify the template arguments for it, it can deduce them automatically.
To have a reference in the tuple, construct it using std::tuple<double, double &>(...)
. Then your code works as you expect it to.