Передача параметра в функцию сравнения?
При использовании алгоритма сортировки 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)
);
}