Home > Enterprise >  Assigning 2 pre-declared variables to function return
Assigning 2 pre-declared variables to function return

Time:11-05

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 since x, 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).

  •  Tags:  
  • c
  • Related