Передача параметра в функцию сравнения?

При использовании алгоритма сортировки STL для вектора я хочу передать свою собственную функцию сравнения, которая также принимает параметр.

Например, в идеале я хочу сделать объявление локальной функции, например:

int main() {
    vector<int> v(100);
    // initialize v with some random values

    int paramA = 4;

    bool comp(int i, int j) {
        // logic uses paramA in some way...
    }

    sort(v.begin(), v.end(), comp);
}

Однако компилятор жалуется на это. Когда я пытаюсь что-то вроде:

int main() {
    vector<int> v(100);
    // initialize v with some random values

    int paramA = 4;

    struct Local {
        static bool Compare(int i, int j) {
            // logic uses paramA in some way...
        }
    };

    sort(v.begin(), v.end(), Local::Compare);
}

Компилятор все еще жалуется: "ошибка: использование параметра из содержащей функции"

Что мне делать? Должен ли я сделать некоторые глобальные переменные с глобальной функцией сравнения.?

Спасибо.

Ответы

Ответ 1

Вы не можете получить доступ к локальным переменным функции из локально определенной функции - С++ в текущей форме не позволяет закрытия. Следующая версия языка, С++ 0x, будет поддерживать это, но языковой стандарт не был доработан, и в настоящий момент поддержка текущего стандартного стандарта практически отсутствует.

Чтобы сделать эту работу, вы должны изменить третий параметр std::sort как экземпляр объекта вместо функции. Третий параметр std::sort может быть любым вызываемым (т.е. Любым x, где добавление круглых скобок, таких как x(y, z), делает синтаксический смысл). Лучший способ сделать это - определить структуру, реализующую функцию operator(), а затем передать экземпляр этого объекта:

struct Local {
    Local(int paramA) { this->paramA = paramA; }
    bool operator () (int i, int j) { ... }

    int paramA;
};

sort(v.begin(), v.end(), Local(paramA));

Обратите внимание, что мы должны хранить paramA в структуре, так как мы не можем получить к ней доступ в противном случае из operator().

Ответ 2

В С++ вы не можете определить свободную функцию внутри другой функции. Таким образом, ваш первый фрагмент кода плохо сформирован.

sort (v.begin(), v.end(), Local:: Compare);

Третий аргумент должен быть функциональным объектом. Перегрузите оператор () внутри класса, а затем создайте объект функции.


В С++ 0x вы можете использовать лямбда-выражения.

auto comp = [&](int m,int n)-> bool {

        return m<n; //or use paramA in some way
    };

sort(v.begin(), v.end(), comp);

Ответ 3

Одна возможность - передать параметр при построении объекта компаратора:

class cmp {
    int param;
public:
    cmp(int p) : param(p) {}

    bool operator()(int i, int j) {
        // logic uses param
    }
};

int main() {
    vector<int> v(100);
    // initialize v with some random values

    int paramA = 4;

    sort(v.begin(), v.end(), cmp(paramA));
}

Ответ 4

//Использование std :: bind

//Пример

{
vector<int> vecInt{2, 4, 10, 20, 30};
    int i = 4;
    sort(vecInt.begin(), vecInt.end(), std::bind( [](int a, int b, int c)
    {
        return abs(a - c) < abs(b - c);
    }, std::placeholders::_1, std::placeholders::_2, i)
    );
}