Как передать адрес экземпляра std :: array в качестве параметра в std :: min_element? - PullRequest
0 голосов
/ 20 сентября 2018

Я пытаюсь прочитать минимальное значение из диапазона в большом фрагменте памяти, я хочу предоставить диапазон памяти функции, а затем найти минимальный элемент.Мне нужно сделать это так, потому что я не могу изменить код или использовать динамическое выделение памяти.

Я использую MinGW-W64-builds-4.3.5 в Win 7.

Iвидел пример в http://www.cplusplus.com/reference/algorithm/min_element/, но они используют массивы в стиле C, которые, как я знаю, я могу использовать в качестве указателей на адреса памяти и выполнять арифметику указателей для обозначения конца диапазона.

// 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;
}

Я пытаюсь сделать что-то подобное с std :: array, но я получаю ошибки компилятора из-за итераторов, есть ли способ сделать что-то подобное с std :: array.Вот мой код:

#define N_ELEMENTS (128u)
short int FindMinElement(const std::array<short int, N_ELEMENTS>& array)
{
    return *(std::min_element(array, array+N_ELEMENTS));
}

Вот мой вывод компилятора:

> 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));

Примечание : я должен быть очень конкретным с диапазоном адресов, так как яя работаю с большим многомерным массивом, поэтому я не могу использовать std :: begin () или std :: end ().Также я не могу работать с вектором, так как мне нужно использовать статическое распределение памяти, а не динамическое.

РЕДАКТИРОВАТЬ:

Спасибо всем за ваши ответы, но я такжездесь есть ограничение, как я уже упоминал выше, массив, который я передаю функции, больше, чем N_ELEMENTS, и это также вызывает ошибку компиляции из-за преобразования типов.Так что решение @PlinyTheElder для меня работало нормально, но я ищу более современное решение, подобное C ++ (C ++ 11 и выше).

Ответы [ 2 ]

0 голосов
/ 20 сентября 2018

Конечно, вы можете!

Вы можете передавать указатели на ваш тип данных в функцию std :: min_element - они служат случайными итераторами.Вам не нужно использовать функции begin() и end(), все указатели на массив будут работать.Пример:

#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;
}
0 голосов
/ 20 сентября 2018

std::array имеет begin и end функции-члены, которые дают вам итераторы в начале и в конце массива.Вы можете использовать их вместо

#define N_ELEMENTS (128u)
short int FindMinElement(const std::array<short int, N_ELEMENTS>& array)
{
    return *std::min_element(array.begin(), array.end());
}

, чтобы получить весь диапазон, или если вам нужен подраздел

#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);
}

Вы также можете рассмотреть что-то вроде

constexpr auto N_ELEMENTS = 128u;

вместо

#define N_ELEMENTS (128u)

для констант.

...