If you really intend that this be used only on arrays, you can simplify its use somewhat by turning the function into a function template that receives its argument by reference (and since we're making it a template anyway, we might as well make it accept a variety of types, not just int
).
template <class T, size_t size>
T peak(const T (&arr)[size]) {
// ...
This way you can just pass the array itself, without explicitly passing the size, so the call in main
turns into something like this:
int arr[] = {1,1,8,9,22,2};
auto elem = peak(arr);
...and the compiler uses its existing knowledge of the number of elements in arr
instead of our having to pass it explicitly (but note that this simply won't work at all for a collection of items allocated with new
or malloc
--if you try to pass a pointer, the code will be rejected).
The obvious alternative (and possibly a superior one) would be to pass iterators instead. This would let us make this algorithm look and feel a lot more like the others in the standard library. A sub-alternative (so to speak) would be to use a range library (e.g., Eric Neibler's) and pass a range instead of separate iterators.
In keeping with the idea of using a template, I'd also consider changing your conditions so they all use the same comparison operator--traditionally C++ has only required operator<
to be defined, and figures everything out from it. In this case it may be more work than it's worth though. It makes no difference for int
, but minimizes the interface required by the template, so it can be applied to types that define <
, but not any other comparison operators. If you don't anticipate applying it to such types, it may be easier to leave it alone.
I'd also consider renaming some of the variables. I see little gain from using arr
instead of array
, for one obvious example.
Headers: right now you have #include <iostream>
, but you use printf
instead of an iostream. I don't see any reason to use printf
in this case--I'd use std::cout << elem;
instead. If, for whatever reason, you want to continue using printf
, include the right header (<cstdio>
) instead of <iostream>
though.
The one question you've asked is eliminated by turning the code into a template. If, for whatever reason, you decide not to do that, you don't need to use decltype. Rather, to compute the number of elements in an array you typically want to use: (sizeof(arr)/sizeof(arr[0]))
(but the template is clearly the better approach).
I'd also prefer to fail loudly, and use some special name for code that checks a pre-condition, such as ensure
or requires
, so if you did pass a pointer, you'd start the code with something like this:
int peak(int const *array, size_t size) {
ensure(array != nullptr);
ensure(size > 0);
...with ensure
defined something like this:
#define ensure(cond) (bool(cond) || fputs(#cond, stderr))
5 4 3 2 1 7 6
. – JS1 13 hours ago