Подтвердить что ты не робот

Синтаксис typedef с указателями функций-членов

в соответствии с MSDN синтаксис typedef:

синоним объявления типа typedef

Очень просто:

typedef int MY_INT;

Но как черт выполняет typedefs-функции-указателя-члена для этого правила?

typedef int (MyClass::*MyTypedef)( int);

100% путаница - синоним (MyTypedef) находится посередине?

Может кто-нибудь объяснить, что логические шаги должны получить из очень простого для понимания формата синтаксиса MSDN в обратном/случайном/переднем/последнем/смешанном синтаксисе, который превосходит typedef?

* edit спасибо за все быстрые ответы (и благоустройство моего сообщения):)

4b9b3361

Ответ 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.

Надеюсь, что это делает его менее запутанным.