Я хочу получить упорядоченные значения индекса на основе вектора (позже я буду использовать эти индексы для сортировки другого вектора). Для моих целей подходит следующий код:

std::vector<int> order_ideal(std::vector<double> x) {
  std::vector<int> idx(x.size());
  std::iota(idx.begin(), idx.end(), 0);
  std::sort(idx.begin(), idx.end(), [&](int i, int j){return x[i] > x[j];});
  return idx;
}

Но лямбда-функции нельзя использовать в более ранних версиях компилятора GCC, поэтому я ищу другой способ реализовать этот код без использования лямбда-функций. Мне очень нравится, как [&] захватывает внешние переменные среды. Другими словами, я хочу использовать x из внешней среды в функции сравнения std::sort().

В качестве альтернативы я мог бы выполнить следующую работу, но на моем компьютере она в шесть раз медленнее, чем указанная выше функция (и я не проверял ее совместимость с более ранними версиями GCC):

bool isGreater(int i, int j, std::vector<double> x)
{
    return x[i] > x[j];
}


std::vector<int> order_bind(std::vector<double> x)
{
  std::vector<int> idx(x.size());
  std::iota(idx.begin(), idx.end(), 0);
  std::sort(idx.begin(), idx.end(), std::bind(isGreater, std::placeholders::_1, std::placeholders::_2, x));
  return idx;
}

Я отчасти понимаю, что мне нужно связать эти два вектора (idx и x вместе), как описано здесь . Но я не могу реализовать это в данном случае.

3
HBat 27 Сен 2020 в 00:45

1 ответ

Лучший ответ

Версия захвата лямбда «сделай сам» - это объект, который захватывает необходимые переменные вручную и предоставляет функтор для выполнения фактической работы, что-то вроде этого (обратите внимание, что я также исправил проблему, которую поднял Сэм):

class Compare
{
public:
    Compare (const std::vector<double> &v) : m_v (v) {}
    bool operator () (int i, int j) const { return m_v [i] < m_v [j]; }

private:
    const std::vector<double> &m_v;
};

std::vector<int> order_ideal(const std::vector<double>& x) {
    std::vector<int> idx(x.size());
    std::iota(idx.begin(), idx.end(), 0);
    Compare c (x);
    std::sort(idx.begin(), idx.end(), c);
    return idx;
}

Live демо

6
Paul Sanders 26 Сен 2020 в 22:12