tags:

views:

184

answers:

7

Is there a more concise way to write the following C++ statements:

int max = 0;

int u = up();
if(u > max)
{
 max = u;
}

int d = down();
if(d > max)
{
max = d;
}

int r = right();
max = r > max ? r : max;  

Specifically is there a way to embed the assignment of the functions return inside the if statement/ternary operator?

+1  A: 

I'd write something like this:

int max = 0;

maximize(max, up());
maximize(max, down());
maximize(max, right());

Where maximize takes the first variable by reference, and a second variable as an offering. If the offering is greater than the first variable, then the first variable is set to the offering.

void maximize(int& v, int offering) {
   if (offering > v) {
      v = offering;
   }
   // or use std::max
}

Benefits

The other alternative to maximize is this one-liner nested-max expression:

// nested-max alternative; more "functional" style
int v = max(max(max(defaultValue, val1), val2), val3);

Contrast this with the multi-step refinement maximization process:

// multi-step maximize alternative; more "imperative" style
int v = defaultValue;
maximize(v, val1);
maximize(v, val2);
// perhaps do something else in between...
maximize(v, val3);

Though not as concise, this latter approach offers the following:

  • A linearized form can be more readable than a deeply nested max expression
  • You can do something in between each maximization steps if you need to
  • The order of the maximization steps are explicit
    • It's also easily to reorder by moving individual statements around

On assignment in condition

And now we address the following part of the question:

Specifically is there a way to embed the assignment of the functions return inside the if statement/ternary operator?

If you insist on doing something like this, you can always use a temporary variable as follows:

int offer;

if ((offer=up()) > max) {
  max = offer;
}
if ((offer=down()) > max) {
  max = offer;
}

max = ((offer=right()) > max) ? offer : max;

This does not result in a very readable code in this case, but there are idiomatic ways to use an assignment in a condition in some scenarios.

Related questions

polygenelubricants
Downvoter: explain?
polygenelubricants
+8  A: 

Assuming that:

  • The idea was to remove the local variables (i.e. you don't need u, d, r later on)
  • Evaluation order doesn't matter

... then you can just use std::max:

int m = max(max(max(0, up()), down()), right());

If this is the return value of the function:

return max(max(max(0, up()), down()), right());

Note that that can evaluate the functions in any order, rather than the string up, down, right order in your original code.

Jon Skeet
what about u, d, r variables ?
bortao
@bortao: I was assuming that the entire point of the question is to render them unnecessary.
Jon Skeet
If you really need the variables, @Bortao, then assign them just like in Alan's code and use them in place the function calls in Jon's code. It might not just be a matter of aesthetics, either. They could be important to guarantee order of evaluation. In Jon's code, `right` might be evaluated before `up` and `down`, even though the original code has it evaluated last.
Rob Kennedy
@Rob: Right - I couldn't remember the details of evaluation order in C++. Will edit to make that clear.
Jon Skeet
+3  A: 
#include <algorithm>
using namespace std;
...

int maxn = max(max(up(), down()), right());

If I'm not mistaken.

Reinderien
+1  A: 
max = std::max(right(), max);
Oli Charlesworth
Out of interest, where do the side-effects come in? Surely each function is going to be executed exactly once either way, right? Admittedly the *ordering* becomes important in my answer - but in your statement here, there's no concern about ordering as far as I can tell.
Jon Skeet
Sorry, you're correct! I was thinking of the C macro. Edited answer accordingly.
Oli Charlesworth
+3  A: 

You can embed assignments, but not variable declarations within the if statements:

int max = 0, u, d, r;

if ((u = up()) > max)
  max = u;

if ((d = down()) > max)
  max = d

max = (r = right) > max ? r : max;
cyberguijarro
+2  A: 
int u = up(), d = down(), r = right();
int max = (u > d) ? u : d;
max = (max > r) ? max : r;

Specifically is there a way to embed the assignment of the functions return inside the if statement/ternary operator?

IMO That would produce terrible legibility

bortao
+1  A: 

I would like to point out that if the execution order of up,down and right is not important, then this sequence should be used:

max(max(0,up()), max(down(),right())

because it minimizes result dependencies and should execute faster on common super scalar CPUs.

Luther Blissett