I have a function that returns std::pair<int, int>
. I also have 2 pre-declared variables x
and y
. I want to do something like this:
int x;
int y;
if (flag) {
x, y = func_that_returns_pair(some args);
} else {
x, y = func_that_returns_pair(some different args);
}
I looked at Can i assign in 2 variables at the same time in C ?, and in C 11, you can use std::tie
. I don't think the auto [x, y]
approach would work here since x, y
are already declared and there's if/else conditioning here. Is there another way to do this besides using std::tie
?
CodePudding user response:
Is there another way to do this besides using
std::tie
?
Yes, you can use a std::pair
with references:
std::pair<int&, int&>(x, y) = func_that_returns_pair(...);
... or a std::tuple
with references:
std::tuple<int&, int&>(x, y) = func_that_returns_pair(...);
CodePudding user response:
You might use a conditional/ternary/whatever-you-want-to-call-it expression to initialize x
and y
using the destructuring syntax.
#include <utility>
#include <iostream>
std::pair<int, int> foo() {
return std::make_pair(6, 7);
}
std::pair<int, int> bar() {
return std::make_pair(3, 4);
}
int main() {
auto [x, y] = true ? foo() : bar();
std::cout << x << y << std::endl;
}
Output:
67
CodePudding user response:
I don't think the
auto [x, y]
approach would work here sincex, y
are already declared
For the code as written, that's true. And this is a recurring problem in fact, since C has a fair few things that can only be initialized, not re-assigned (not even a std::tie
-like solution exists for constant objects).
Fortunately, we can always put such logic - no matter how complex - into functions that return the initial value for our declaration. And since C 11, we can even write the function inline as an immediately invoked lambda.
auto [x, y] = [&]{
if (/*some condition*/) {
return func_that_returns_pair(/*some args*/);
}
if(/*some other condition*/){
return func_that_returns_pair(/*some different args*/);
}
return func_that_returns_pair(/*Some default args*/);
}();
Very handy in a quick refactor, since it doesn't require passing a lot of context into the call (we can just capture that context in scope of the declaration).