Our C++ professor told us to practise the use of std::function, lambda and pointers to functions. He asked us to:
Write the function
std::function<bool(float)> interval(float low, float high)
. The function should accept two valueslow
andhigh
and should return a function. The function returned will check if it's parameter is inside or outside the interval (low,high) and will returntrue
orfalse
accordingly.
I tackled the problem with this code.
The function declaration:
std::function<bool(float)> interval (float low,float high){
return [low,high](float f){ return (f > low) && (f < high); };
}
How is it used in the main:
std::function<bool(float)> interval (float low,float high);
bool res = interval(10, 20)(150);
std::cout << res;
And it works. But I am not sure how the solution is elegant, or "best practise".
In particular, this call bool res = interval(10, 20)(150);
is what scares me.
It is really awful to call it like this.
How would you have done the excersize? Do you find my solution clear?
1 Answer 1
This looks like it almost conforms to the spec (I think those tests should be >=
and <=
given that's an inclusive interval). You might want to consider what happens if a NaN value is passed in - since they are neither less-than nor greater-than actual numbers, we'll return false
, which seems reasonable. It's probably not a good idea to create an interval with NaN as start or end of the range, though!
Though it wasn't your choice, I would question the use of float
rather than double
here (actually, in real code, I'd probably make it a template function so it can work with any type that has a partial ordering).
If you don't like the chained call syntax, you can separate out using a variable, and that's likely to be a more common case than building and immediately using just once as shown in the question:
auto is_valid = interval(10, 20);
for (auto v: values) {
if (!is_valid(v)) {
std::cerr << v << " out of range\n";
}
}
interval(10, 20, 150)
that would be wrong. \$\endgroup\$auto isLegalSpeed = interval(0, 60);
and on another lineif isLegalSpeed(currentSpeed)
which would be a lot more readable thanif interval(0, 60, currentSpeed)
\$\endgroup\$speedCheck[highway] = interval(50, 70);
andspeedCheck[city] = interval(10, 30);
That allows for very powerful constructions indeed: if you had a list of speed camera readings from a list of roads, you could then testspeedCheck[roadType](speed)
for each reading instead of the much more verboseif roadType == city {...
\$\endgroup\$