Синтаксис указателя на функцию C ++ - PullRequest
3 голосов
/ 05 апреля 2011

Я знаю, что обычно указатель функции объявляется так:

 void __stdcall my_func(int i) {} // for assigning

 void (__stdcall * my_ptr)(int) = &my_func;

Теперь у меня было несколько функций, которые принимают указатель на функцию в качестве аргумента:

 void calling_func(void (__stdcall * callback)(int)) { *callback(1); }

В заголовочном файле я просто убрал название вещи:

void calling_func(void (__stdcall *)(int));

и вуаля, это сработало ... и заставило меня задуматься: если это полное объявление типа, нельзя ли использовать обычный синтаксис TYPE NAME = VALUE также для указателей на функции?

Я пытался объявить:

 ( void (__stdcall *)(int) ) callback = &my_func;

и он также компилируется! Почему это не используется чаще? Есть ли недостатки в этой записи? Мне кажется, что это значительно облегчило бы использование указателей на функции ... также в typedefs, например: обычно это typedef OLDNAME NEWNAME, просто с указателями на функции это тот странный синтаксис наизнанку, где новое имя фактически находится в середине всего выражения. Не говоря уже о записи для функций, возвращающих указатель на функцию ...

Ответы [ 3 ]

4 голосов
/ 05 апреля 2011

Это не объявление, это приведение callback, которое затем присваивается.

Вы уверены, что у вас не было ранее существующего объявления в области действия?

4 голосов
/ 05 апреля 2011

Не компилируется для меня. AFAIK, это не действительно C ++.

Вы можете подделать это, хотя!

template <typename T>
struct identity {
   typedef T type;
};

identity<void(*)(int)>::type callback = &my_func;

Или используйте что-то вроде boost::function (или std::function) для окончательных побед.

1 голос
/ 05 апреля 2011

Я очень предпочитаю typedef использование моих указателей на функции, и у меня еще не было проблем с ним.

Typedef, если я правильно понимаю, не столько создает новый тип, сколько псевдоним длядругой (именно поэтому size_t и unsigned int могут использоваться взаимозаменяемо, например, без жалоб компилятора).Таким образом, для типов указателей на функции, которые вы часто используете, typedefs упрощают работу с ними.

Для указателей на функции typedefs синтаксис выглядит так:

typedef IObject *    (*CreateFunc )(int, Core *);

С нужным именем типа навнутри (не сильно отличается от того, что вы делаете сейчас).Вы можете указать большинство модификаторов функций (__stdcall, __declspec и т. Д.), Они располагаются внутри скобок перед * name.

Вы можете вызывать, присваивать и получать их значения довольно легко, а также конвертироватьих на void * для передачи (когда тип неизвестен).

...