Search code examples
c++reference

c++ Assigning reference variable in an if statement


How can I assign a reference variable based on an if statement?

For example, the following example doesn't work because "smaller" doesn't have scope outside of the if-statement.

int x = 1;
int y = 2;
if(x < y)
{
    int & smaller = x;
}
else if (x > y)
{
    int & smaller = y;
}
/* error: smaller undefined */

However, the following example also doesn't work because references must be assigned to objects immediately.

int x = 1;
int y = 2;
int & smaller; /* error: requires an initializer */
if(x < y)
{
    smaller = x;
}
else if (x > y)
{
    smaller = y;
}

I could achieve the reference assignment with a ternary-if statement, but what if I can't use that? ternary-if only works for simplest cases, but not multiple else-ifs or assigning multiple reference variables per block.

I've heard advice to "avoid pointers until you can't" because they are more error-prone than references. I was just wondering if this is a case where I can't avoid them.


Solution

  • use a function:

    int &foo(int &x, int &y) {
      if(x < y)
      {
        return x;
      }
      else if (x > y)
      {
        return y;
      } else {
        // what do you expect to happen here?
        return x;
      }
    }
    
    int main() {
      int x = 1;
      int y = 2;
      int & smaller = foo(x, y); /* should work now */
    }
    

    Note, in your case, I would even expect foo to return a const int& as it would seem strange to modify the value identified as smaller, but as you did not use it const in you question, i keep it like this.

    EDIT:

    With C++ 11 and above, you can use a lambda that you call on the go:

    int main() {
      int x = 1;
      int y = 2;
      int & smaller = [&]() -> int & {
        if(x < y)
        {
          return x;
        }
        else if (x > y)
        {
          return y;
        } else {
          // what do you expect to happen here?
          return x;
        }
      }(); /* should work now */
    }