Use auto for only one variable with structured binding

A third option:

decltype(func(y).first) x;
std::tie(x, y) = func(y);

A structured binding is a declaration; it cannot be used e.g. for assignment into an already declared variable.

If you are allowed to move the declaration of y and you ever only need it to make a function call, you could abuse the scope of the the capture list of an immediately invoked lambda, and let it shadow (only within the scope of the lambda) the variable y that is declared as part of a structured binding, which is in turn initialized using the return from the immediately invoked lambda:

auto [x, y] = [y = 1.0](){ return func(y); }();
            // ^^^^^^^ actually not at all in namespace scope,
            //         but a data member of the closure type
            //         of the lambda expression.

You could likewise use a named lambda:

const auto l = [y = 1.0](){ return func(y); };
auto [x, y] = l();

As is typically the case with shadowing alongside the somewhat complex scoping rules of C++, this is likely only to confuse readers, though.

Tags:

C++

C++17