Передача параметра в функцию сравнения? - PullRequest
19 голосов
/ 01 ноября 2010

При использовании алгоритма сортировки 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);
}

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

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

Спасибо.

Ответы [ 4 ]

28 голосов
/ 01 ноября 2010

Вы не можете получить доступ к локальным переменным функции изнутри локальной функции - C ++ в ее текущей форме не допускает замыкания . Следующая версия языка, C ++ 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().

12 голосов
/ 01 ноября 2010

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

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

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


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

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

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

sort(v.begin(), v.end(), comp);
5 голосов
/ 01 ноября 2010

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

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));
}
0 голосов
/ 11 января 2019

// Использование 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)
    );
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...