I'm trying to read the minimum value from a range in a big chunk of memory, I want to provide the memory range to a function and then find the minimum element. I need to do it this way because I can not change the code or use dynamic memory allocation.
I'm using MinGW-W64-builds-4.3.5 in Win 7.
I saw an example in http://www.cplusplus.com/reference/algorithm/min_element/ but they are using C style arrays which I know I can use as pointers to memory addresses and perform pointer arithmetic to indicate the end of the range.
// min_element/max_element example
#include <iostream> // std::cout
#include <algorithm> // std::min_element, std::max_element
bool myfn(int i, int j) { return i<j; }
struct myclass {
bool operator() (int i,int j) { return i<j; }
} myobj;
int main () {
int myints[] = {3,7,2,5,6,4,9};
// using default comparison:
std::cout << "The smallest element is " << *std::min_element(myints,myints+7) << '\n';
std::cout << "The largest element is " << *std::max_element(myints,myints+7) << '\n';
// using function myfn as comp:
std::cout << "The smallest element is " << *std::min_element(myints,myints+7,myfn) << '\n';
std::cout << "The largest element is " << *std::max_element(myints,myints+7,myfn) << '\n';
// using object myobj as comp:
std::cout << "The smallest element is " << *std::min_element(myints,myints+7,myobj) << '\n';
std::cout << "The largest element is " << *std::max_element(myints,myints+7,myobj) << '\n';
return 0;
}
I'm tyring to do something similar with std::array but I'm getting compiler errors, due to the iterators, is there a way to do something similar with std::array. Here is my code:
#define N_ELEMENTS (128u)
short int FindMinElement(const std::array<short int, N_ELEMENTS>& array)
{
return *(std::min_element(array, array+N_ELEMENTS));
}
Here is my compiler output:
> Executing task: g++.exe -Wall -g c:\Users\uidr8361\Desktop\C++\Tmp\ReadArcPixels.cpp <
c:\Users\uidr8361\Desktop\C++\Tmp\ReadArcPixels.cpp: In function 'short int FindMinElement(const std::array<short int, 128>&)':
c:\Users\uidr8361\Desktop\C++\Tmp\ReadArcPixels.cpp:41:55: error: no matching function for call to 'min_element(const std::array<short int, 128>&, const std::array<short int, 128>*)'
return *(std::min_element(array, &array+N_ELEMENTS));
^
In file included from C:/mingw64/lib/gcc/x86_64-w64-mingw32/8.1.0/include/c++/algorithm:62,
from c:\Users\uidr8361\Desktop\C++\Tmp\ReadArcPixels.cpp:4:
C:/mingw64/lib/gcc/x86_64-w64-mingw32/8.1.0/include/c++/bits/stl_algo.h:5610:12: note: candidate: 'template<class _FIter> constexpr _FIter std::min_element(_FIter, _FIter)'
inline min_element(_ForwardIterator __first, _ForwardIterator __last)
^~~~~~~~~~~
C:/mingw64/lib/gcc/x86_64-w64-mingw32/8.1.0/include/c++/bits/stl_algo.h:5610:12: note: template argument deduction/substitution failed:
c:\Users\uidr8361\Desktop\C++\Tmp\ReadArcPixels.cpp:41:55: note: deduced conflicting types for parameter '_FIter' ('std::array<short int, 128>' and 'const std::array<short int, 128>*')
return *(std::min_element(array, &array+N_ELEMENTS));
^
In file included from C:/mingw64/lib/gcc/x86_64-w64-mingw32/8.1.0/include/c++/algorithm:62,
from c:\Users\uidr8361\Desktop\C++\Tmp\ReadArcPixels.cpp:4:
C:/mingw64/lib/gcc/x86_64-w64-mingw32/8.1.0/include/c++/bits/stl_algo.h:5635:5: note: candidate: 'template<class _FIter, class _Compare> constexpr _FIter std::min_element(_FIter, _FIter, _Compare)'
min_element(_ForwardIterator __first, _ForwardIterator __last,
^~~~~~~~~~~
C:/mingw64/lib/gcc/x86_64-w64-mingw32/8.1.0/include/c++/bits/stl_algo.h:5635:5: note: template argument deduction/substitution failed:
c:\Users\uidr8361\Desktop\C++\Tmp\ReadArcPixels.cpp:41:55: note: deduced conflicting types for parameter '_FIter' ('std::array<short int, 128>' and 'const std::array<short int, 128>*')
return *(std::min_element(array, &array+N_ELEMENTS));
Note : I have to be very specific with the range of addresses since I'm working with a big multi-dimensional array so I can not use std::begin() or std::end(). Also I cannot work with vector since I'm need to use static memory allocation and not dynamic.
EDIT:
Thanks everybody for your answers but I'm also having a constraint here, as I mentioned above the array I'm passing to the function is bigger than the N_ELEMENTS
and that also causes a compilation error due to the type conversion. So @PlinyTheElder solution worked fine for me but I'm looking for a more modern C++ (C++11 onwards) like solution.
std::array
has begin
and end
member functions that give you iterators to the begining and one past the end of the array. You can use those instead like
#define N_ELEMENTS (128u)
short int FindMinElement(const std::array<short int, N_ELEMENTS>& array)
{
return *std::min_element(array.begin(), array.end());
}
to get the entire range or if you need a sub section
#define N_ELEMENTS (128u)
short int FindMinElement(const std::array<short int, N_ELEMENTS>& array)
{
return *std::min_element(array.begin(), array.begin() + N_ELEMENTS);
}
You might also want to consider something like
constexpr auto N_ELEMENTS = 128u;
instead of
#define N_ELEMENTS (128u)
for constants.
Of course you can!
You can pass pointers to your data type into the std::min_element function - they serve as random iterators. You don't need to use the begin()
and end()
functions, any pointers into the array will work. Example:
#include <array>
#include <algorithm>
#include <iostream>
int main()
{
std::array<int,1000> arr;
size_t size = arr.size();
int* start = &arr[0];
int* finish = start + size;
for (int* i = start; i < finish; ++i) *i = rand();
int* minP = std::min_element(start, finish);
int minVal = *minP;
std::cout << minVal;
}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.