Home > front end >  Chaining multiple function calls inside an if statement in C 17
Chaining multiple function calls inside an if statement in C 17

Time:01-06

Let's say I have this as current code:

if (GetFlag(...)) {
  if (auto x = GetX(...)) {
     if (auto y = GetY(...)) {
         ...
     }
  }
}

and that the method calls and variable definitions need to be made in this order for both correctness and performance reasons (we don't want to calculate x if GetFlag(...) returns false, and we don't want to calculate y if x is nullptr).

Is there a way to refactor this into a "one-liner"? The closest I got to actually compiling would be

if (auto x = GetX(...); auto x = GetX(...) && GetFlag(...)) { ... }

but this does not preserve the order of operations.

Thanks!

CodePudding user response:

You can extract the conditionals into a separate function that returns a tuple, and structured bind in the if

std::tuple<bool, std::optional<X>, std::optional<Y>> getFlagsXY()
{
    if (!getFlags())
    {
        return { false };
    }
    
    if (auto x = getX(); !x)
    {
        return { true, std::move(x) };
    }
    else 
    {
        return { true, std::move(x), getY() };
    }
}

if (auto [f, x, y] = getFlagsXY(); f && *x && *y) { ... }

CodePudding user response:

And yes it is possible. If statements stop processing terms once they see which branch is going to be taken. Try changing the values of GetFlag, GetX to see when the body of the if gets called.

#include <iostream>

bool GetFlag()
{
    std::cout << "GetFlag\n";
    return true;
}

int GetX()
{
    std::cout << "GetX\n";
    return 0;
}

int GetY()
{
    std::cout << "GetY\n";
    return 3;
}


int main()
{
    int x;
    int y;

    if (GetFlag() && (x = GetX()) && (y = GetY()))
    {
        std::cout << "Do " << x << ", " << y;
    }

    return 0;
}
  •  Tags:  
  • c
  • Related