Ваша проблема
Вы пытались создать двумерный массив в стеке (это не является стандартным C++
, хотя это может работать на некоторых компиляторах). Для этого необходимо знать размер во время компиляции, а это не так, когда вы вызываете size()
для объекта, который, вероятно, не является constexpr.
БЫСТРЫЙ ИСПРАВЛЕНИЕ
Быстрое исправление, которое работает «из коробки», состоит в том, чтобы просто выделить память в куче ( не забудьте позже удалить массив ), выполнив
float** aDistances = new float[N][N];
Удаление можно выполнить с помощью функции, которая выглядит следующим образом
template <typename T>
void delete2DArray(T** ptr, size_t NumRows)
{
for (size_t i = 0; i < NumRows; i++)
{
delete[] ptr[i];
}
delete[] ptr;
}
FIX
Вам придется использовать динамическое распределение памяти. Для этого вы можете попробовать следующий подход, добавив класс-оболочку вокруг std :: vector (это должно быть возможно, поскольку вы сказали, что область действия очень управляема)
template <typename T>
class Array2D
{
public:
Array2D(size_t numrows, size_t numcols) :
rows(numrows), columns(numcols), array2d(rows * columns)
{}
T& operator()(size_t row, size_t column)
{
return array2d[row * columns + column];
}
const T& operator()(size_t row, size_t column) const
{
return array2d[row * columns + column];
}
T* getRow(size_t row)
{
return &array2d[row * columns];
}
private:
size_t rows;
size_t columns;
std::vector<T> array2d;
};
Чем вы должны изменить свой код следующим образом:
// Compute distances between them
const size_t N = vDescriptors.size();
Array2D<float> aDistances(N,N);
for (size_t i = 0; i < N; i++) {
aDistances(i,i) = 0;
for (size_t j = i + 1; j < N; j++) {
int distij = ORBmatcher::DescriptorDistance(vDescriptors[i], vDescriptors[j]);
aDistances(i,j) = distij ;
aDistances(j,i) = distij ;
}
}
Как видите, синтаксис для доступа к элементам немного изменился [x] [y] -> (x, y).
EDIT
Поскольку ОП изменил вопрос, я заметил, что Distances
используется второй раз, что также требует внимания. Для этого вам нужно будет добавить метод getColumn
(см. Выше) в класс Array2D
. Чем дальше нужно модифицировать
// Take the descriptor with least median distance to the rest
int BestMedian = INT_MAX;
int BestIdx = 0;
for(size_t i=0;i<N;i++) {
vector<int> vDists(aDistances.getRow()[i], aDistances.getRow()[i]+N);
sort(vDists.begin(),vDists.end());
int median = vDists[0.5*(N-1)];
if(median<BestMedian) {
BestMedian = median;
BestIdx = i;
}
}
ПРИМЕЧАНИЕ: Я не совсем уверен, правильно ли я понял - возможно, вам нужно получить
столбцы вместо строк (слишком поздно, чтобы думать прямо). В этом случае вам также следует изменить макет памяти класса Array2D, то есть отсортировать элементы по-разному в нижележащем 1D-векторе.