Отключение предупреждения «плохая функция приведения» - PullRequest
10 голосов
/ 13 июля 2011

Я получаю следующее предупреждение:

warning: converting from 'void (MyClass::*)(byte)' to 'void (*)(byte)'

Это потому, что мне нужно передать в качестве аргумента функцию-член вместо обычной функции.Но программа работает правильно.

Я бы хотел отключить это предупреждение (Wno-bad-function-cast не работает для C ++) или реализовать другой способ передачи функции-члена.

Ответы [ 3 ]

16 голосов
/ 13 июля 2011

Нет . Относитесь к этому предупреждению серьезно. Вы должны изменить свой код для обработки этого сценария.

Указатель на функцию-член (void (MyClass::*)(byte)) и указатель на обычную функцию (void (*)(byte)) совершенно разные. Смотрите эту ссылку . Вы не можете разыграть их просто так. Это приводит к неопределенному поведению или падению.

Смотрите здесь, чем они отличаются:

void foo (byte); // normal function
struct MyClass {
  void foo (byte); // member function 
}

Теперь вы можете почувствовать, что foo(byte) и MyClass::foo(byte) имеют одинаковую сигнатуру, тогда почему их указатели на функции НЕ одинаковы. Это потому, что MyClass::foo(byte) внутренне разрешено в некоторой степени as,

void foo(MyClass* const this, byte);

Теперь вы можете почувствовать разницу между ними.

Объявить указатель на функцию-член как,

void (MyClass::*ptr)(byte) = &MyClass::foo;

Вы должны использовать это ptr с объектом MyClass, таким как:

MyClass obj;
obj.*ptr('a');
0 голосов
/ 13 июля 2011

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

По той же причине вы не можете передать нестатическую функцию-член, где ожидается обычная функция.Функция-член нуждается в объекте для работы.Какой бы код ни вызывал вашу функцию, он не знает об объекте, нет способа передать ему объект, и нет способа заставить его использовать правильную последовательность вызова, которая учитывает объект.

Интерфейсы, которые принимаютФункции пользователя, не принимая дополнительных данных, которые пользователь может захотеть передать своей функции, по своей сути злые.Посмотрите на функцию qsort() из стандартной библиотеки C.Это пример злого интерфейса.Предположим, вы хотите отсортировать массив строк в соответствии с определенной схемой сопоставления, определенной извне.Но он принимает только функцию сравнения, которая принимает два значения.Как передать эту схему сопоставления в функцию сравнения?Вы не можете, и поэтому, если вы хотите, чтобы это работало, вы должны использовать злую глобальную переменную со всеми присоединенными к ней строками.

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

0 голосов
/ 13 июля 2011

Также это может быть полезно

union FuncPtr    
{
  void (* func)(MyClass* ptr, byte);
  void (MyClass::* mem_func)(byte);
};
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...