Имеем:
typedef void (*xbswap)(unsigned char*, long unsigned int);
void xClass::BSwap(BYTE*, DWORD);
Функция:
static bool fun1(xbswap cb_swap) { ... }
Вызываем из класса xClass:
fun1((xbswap)&BSwap));
И в месте вызова имеем предупреждение:
warning: converting from 'void (xClass::*)(BYTE*, DWORD)'
{aka 'void (xClass::*)(unsigned char*, long unsigned int)'} to 'xbswap'
{aka 'void (*)(unsigned char*, long unsigned int)'} [-Wpedantic]
...
Как разумно поправить? кроме выключения варнинга..
Если у вас есть полная свобода в выборе интерфейса вашего static bool fun1(...), то вы можете изначально реализовать ее через функтор, а не через указатель на функцию. Либо
template <typename F>
static bool fun1(F cb_swap) // или const F &cb_swap
{
...
cb_swap(byte_ptr, dw);
...
}
либо
static bool fun1(const std::function<void (BYTE*, DWORD)> &cb_swap)
{
...
cb_swap(byte_ptr, dw);
...
}
Первый вариант более эффективен, но за это приходится платить "размножением" foo: отдельной версией foo для каждого значения шаблонного параметра F. Вторая версия не является шаблонной, т.е. не "размножается" для разных типов аргументов, но за это приходится платить внутренними накладными расходами std::function.
Тогда у вас будет полная свобода в конструировании этого функционального объекта для передачи в fun1, включая использование std::bind
// Внутри метода `xClass`
using namespace std::placeholders;
fun1(std::bind(&xClass::BSwap, this, _1, _2));
По таким причинам в С++ рекомендуется сразу проектировать интерфейсы в терминах функциональных объектов (а не указателей на функции) всегда, когда это возможно. Это не всегда возможно: интерфейсы могут быть навязаны посторонним кодом, в т.ч. написанным на С. Но если в данном случае вы контролируете весь код, то такую возможность стоит рассмотреть.
Сборка персонального компьютера от Artline: умный выбор для современных пользователей