gcc delegate converting warning

162
24 июня 2019, 12:10

Имеем:

  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]
  ...

Как разумно поправить? кроме выключения варнинга..

Answer 1

Если у вас есть полная свобода в выборе интерфейса вашего 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));

По таким причинам в С++ рекомендуется сразу проектировать интерфейсы в терминах функциональных объектов (а не указателей на функции) всегда, когда это возможно. Это не всегда возможно: интерфейсы могут быть навязаны посторонним кодом, в т.ч. написанным на С. Но если в данном случае вы контролируете весь код, то такую возможность стоит рассмотреть.

READ ALSO
Опережающее объявление typedef типа

Опережающее объявление typedef типа

Есть libpq, там есть объявление:

163
Вывести массив чисел без повторений

Вывести массив чисел без повторений

Дан отсортированный по возрастанию массив C (например, {2, 2, 2, 3, 3})Нужно вывести в консоль этот же массив C без повторений (то есть должно получиться...

145
Узнать тип на этапе компиляции

Узнать тип на этапе компиляции

Можно ли определить тип переданных параметров variadic templates, на этапе компиляции?

139
Qt C++ Несколько диапазонов с разрывом в QSpinBox, QDoubleSpinBox

Qt C++ Несколько диапазонов с разрывом в QSpinBox, QDoubleSpinBox

Как в QSpinBox, QDoubleSpinBox задать некоторый множественный диапазон? Примеры как должен работать этот SpinBox, аналогично для DoubleSpinBox: 1) Должен принимать...

143