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?
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.
#include <algorithm>
using namespace std;
...
int maxn = max(max(up(), down()), right());
If I'm not mistaken.
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;
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
max = std::max(right(), max);
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
- Why would you use an assignment in a condition?
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.
The more generic problem is finding the max of the given inputs. We can generalise std::max
to something like this:
template <typename T, typename ... Ts>
T Max (const T && input_1, const Ts && ... inputs)
{
// initialise:
T max = input_1;
// find max:
([&] (T i)
{
if (i > max)
max = i;
} (inputs), ...);
return max;
}
(above is c++17
style, but we can write the same thing in a less pretty way in earlier c++
)
This makes finding the max like so:
int max = Max<int>(0, up(), down(), right());
We add the <int>
to specify what we want to convert the inputs to, in case some are unsigned
, float
, etc.
If the order of calls actually does matter, then there's not much better we can do than this:
int max = 0;
max = std::max(max, up());
max = std::max(max, down());
max = std::max(max, right());
We could make a generic function, like Max
above, that takes in a list of functions/functors instead, but it's such an unusual issue that I doubt you'd re-use the code.
精彩评论