Как использовать функцию-член с std :: bsearch

У меня есть класс C ++, но я также использую какой-то низкий уровень C, и мне нужно использовать bsearch функция. Последний аргумент bsearch является функцией сравнения, и я хочу реализовать указанную функцию таким образом, чтобы она могла получить доступ к закрытым переменным const класса.

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

Что делать?

пример:
введите описание изображения здесь

3 означает, что есть 3 элемента. 16, 32, 56 — это смещенные байты. Мне нужен bsearch для поиска акторов. Я ищу в массиве смещений. Мне нужна функция сравнения, которая бы сравнивала актеров, но я также нуждаюсь в const void * actorFile указатель для вычисления местоположения в функции сравнения .actorFIle является закрытой переменной класса.

3

Решение

Решение состоит в том, чтобы отказаться от функции библиотеки C и использовать C ++ в том виде, в котором он предназначен. Стандартная библиотека C ++ также имеет функцию поиска утилиты, она называется std::lower_bound. И он принимает общие функционально-подобные объекты, а не только обычные указатели функций.

Это позволяет вам вызывать его с помощью лямбда-выражения, которое захватывает ваш класс:

std::lower_bound(start, finish, value, [this] (auto const& lhs, auto const& rhs) {
/* Compare and utilize anything this can point to*/ });
7

Другие решения

Если вы действительно привязаны к bsearch просто используйте вашу функцию-член внутри функции, не являющейся членом. Следовательно, вам не нужен доступ к частным пользователям.

/* Create global variable to use in compare proc*/
actors_data_base* cmp_data_base = NULL;

/* Write compare routine like */
int cmp_proc(const void * a, const void * b)
{
size_t a_offset = static_cast<size_t>(a);
size_t b_offset = static_cast<size_t>(b);
return cmp_data_base->compare_actors(a_offset, b_offset);
}/* Set global pointer and use bsearch */
actors_data_base = &my_data_base;
bsearch(&my_value, array, size, sizeof(size_t), cmp_proc);

Определенно, это ужасно из-за использования глобальной переменной. Но это единственный способ передать контекст для сравнения процедур. Вы можете подумать об использовании локального хранилища потоков, чтобы избежать проблем с потоками (cmp_proc не должен использоваться одновременно из-за глобальной переменной)

Следовательно, вы бы гораздо лучше использовать std::lower_bound.

1