Синтаксис typedef с указателями функций-членов
в соответствии с MSDN синтаксис typedef:
синоним объявления типа typedef
Очень просто:
typedef int MY_INT;
Но как черт выполняет typedefs-функции-указателя-члена для этого правила?
typedef int (MyClass::*MyTypedef)( int);
100% путаница - синоним (MyTypedef
) находится посередине?
Может кто-нибудь объяснить, что логические шаги должны получить из очень простого для понимания формата синтаксиса MSDN в обратном/случайном/переднем/последнем/смешанном синтаксисе, который превосходит typedef?
* edit спасибо за все быстрые ответы (и благоустройство моего сообщения):)
Ответы
Ответ 1
синоним (MyTypedef) находится в середине
Это не посередине. Просто забудьте функцию-член какое-то время, посмотрите, как определяется указатель функции:
int (*FuncPtr)(int);
И вот как бы вы это сделали:
typedef int (*FuncPtr)(int);
Simple! Единственное отличие состоит в том, что typedef FuncPtr
становится типом, а в объявлении указателя FuncPtr
является переменной.
Аналогично,
int (MyClass::*MyTypedef)( int); //MyTypedef is a variable
И typedef как:
typedef int (MyClass::*MyTypedef)( int); //MyTypedef is a type!
Ответ 2
Как вы определяете указатель на функцию-член? Вот так:
int (A::*variableName)(int);
Чтобы сделать это typedef, просто добавьте typedef:
typedef int (A::*typedefName)(int);
Ответ 3
Стоит отметить, что с С++ 11 вы могли бы написать это выражение как более четкое выражение using
:
using MyTypedef = int (MyClass::*)(int);
Ответ 4
Я знаю, что вы уже получили свой ответ, но хотите поделиться этим - это удобно: http://www.cdecl.org. Это переводчик C/С++ ↔ Английский переводчик. Просто введите
объявить x как указатель на член функция класса A (int), возвращающая char
и вы получите char (A::*x)(int )
. Или поиграйте с декларацией и посмотрите, получаете ли вы то, что хотите.
Ответ 5
Принцип объявления в С++ заключается в том, что они имитируют использование. Если вы хотите использовать указатель на функцию члена pmf, вы напишете:
(myVar.*pmf)(arg);
поэтому для определения typedef для него вы пишете:
typedef int (MyClass::*pmf)(int);
добавление возвращаемого типа в голову, заменяя переменную типом и аргументами по типу.
Ответ 6
Я когда-то читал приятное объяснение (но это из Expect C Programming, поэтому я ymmv):
Фактически, typedef имеет точно в том же формате, что и объявление переменной, только с этим дополнительным ключевым словом вы отключились.
Так как typedef выглядит точно так же, как объявление переменной, оно читается точно так же, как один. Вместо декларация о том, что "это имя относится к переменной указанного типа, Ключевое слово typedef не создает переменная, но вызывает объявление сказать" это имя является синонимом указанный тип.
Итак, у вас это есть. Представьте, что вы объявляете переменную, придерживайтесь typedef
перед ней и вуаля, у вас есть новый тип. MSDN
объяснения - это смешанная сумка: я читал действительно божественные и совершенно плохие.
Ответ 7
Страница, на которую вы ссылаетесь, вероятно, " typedef Specifier". Упрощенный "typedef type-declaration synonim;
" синтаксис является лишь одним из многих способов использования typedef. Существует (возможно) нет простого и краткого описания того, как можно использовать typedef. Вот что означает "" Объявления о типепедах" для страницы MSDN.
Вы увидите на этой странице что-то вроде:
declaration:
declaration-specifiers init-declarator-list opt ;
declaration-specifiers:
storage-class-specifier declaration-specifiers opt
type-specifier declaration-specifiers opt
type-qualifier declaration-specifiers opt
storage-class-specifier:
typedef
Подробнее о том, какие объявления-спецификаторы и список init-declarator можно найти здесь.
Это один из строгих способов понять все возможные способы использования "typedef".
В этой статье в основном говорится, что перед большинством действительных объявлений можно использовать "typedef".
Ответ 8
Синтаксис использования указателя функции-члена должен (предположим, что a
является экземпляром класса a
):
- в объявлении используйте "A::" в качестве префикса
- при использовании, используйте "a". как префикс
Ниже приведен пример игрушек. Вы можете играть с ним.
#include <stdio.h>
#include <stdlib.h>
class A;
typedef int (A::*F)(double);
class A {
public:
int funcDouble(double x) { return (int)(x * 2.0); }
int funcTriple(double x) { return (int)(x * 3.0); }
void set(int a) {
if (a == 2) {
this->f_ = &A::funcDouble;
} else if (a == 3) {
this->f_ = &A::funcTriple;
} else {
this->f_ = NULL;
}
}
public:
F f_;
};
int main(int argc, char *argv[]) {
A a;
a.set(2);
F f = &A::funcDouble;
printf("double of 1 = %d\n", (a.*f)(1));
// Below is equivalent to:
// F f2 = a.f_;
// printf("double of 1 = %d\n", (a.*f2)(1));
printf("double of 1 = %d\n", (a.*(a.f_))(1));
a.set(3);
printf("triple of 1 = %d\n", (a.*(a.f_))(1));
return 0;
}
Ответ 9
Легче понять, когда вы начнете думать так:
Всякий раз, когда вы видите такую функцию:
TYPE foo(int arg1, int arg2);
Вы говорите, что тип foo - TYPE. Таким образом, тип
int get_next_prime();
- int.
Вы можете видеть, что при передаче указателя функции в качестве аргумента функции:
void register_callback(void (*ptr)(int));
В этом случае вы передаете функцию типа void в качестве аргумента.
Теперь, когда вы видите что-то подобное:
typedef int (A::*typedefName)(int);
вы просто говорите, что переменная (A:: * typedefName) (int) (это только одна вещь, а не две, так как это объявление указателя функции) на самом деле имеет тип int. С этого момента компилятор интерпретирует A:: * typedefName как функцию типа int, то есть возвращает значение int.
Надеюсь, что это делает его менее запутанным.
Ответ 10
Здесь полное и точное описание: http://tipsandtricks.runicsoft.com/Cpp/MemberFunctionPointers.html