Сложные объявления

type FunctionName = (n: returnType) => any;

class ClassName {
    save(callback: FunctionName) : void {
        callback(data);
    }
}

Это, безусловно, совпадает с парадигмой функционального программирования.

13
задан Peter Mortensen 1 January 2016 в 20:53
поделиться

7 ответов

Вот отличная статья о том, как читать сложные объявления на C: http://www.codeproject.com/KB/cpp/complex_declarations.aspx

Мне помогло много!

Особенно - Вам стоит прочитать раздел «Правильное правило». Вот цитата:

int * (* (* fp1) (int)) [10]; Это можно интерпретировать следующим образом:

  1. Начать с имени переменной -------------------------- fp1
  2. Ничего правильного, кроме) поэтому идите влево, чтобы найти * -------------- - указатель
  3. Выйдите из скобок и встретите (int) --------- на функция, которая принимает в качестве аргумента int
  4. Идите налево, найдите * ----------------------------------- ----- и возвращает указатель
  5. . Переместите скобки, перейдите вправо и нажмите [10] -------- на массив 10
  6. Идите налево, найдите * ----------------------------------------- указатели to
  7. Снова идите налево, найдите int -------------------------------- ints.
18
ответ дан 1 December 2019 в 17:29
поделиться

Вы можете использовать cdecl * :

cdecl> explain int *( *( *a[5])())();
 declare a as array 5 of pointer to function
 returning pointer to function returning pointer to int
cdecl> explain int * (* (*fp1) (int) ) [10];
 declare fp1 as pointer to function (int) returning
 pointer to array 10 of pointer to int

* Linked - это веб-сайт, который использует этот инструмент командной строки в серверной части.

17
ответ дан 1 December 2019 в 17:29
поделиться

Для решения этих сложных объявлений необходимо помнить о том, что приоритет оператора вызова функции () и оператора индекса массива [] выше, чем оператора разыменования *. Очевидно, скобки () могут использоваться для переопределения этих приоритетов.

Теперь определите свое объявление от середины, что означает от имени идентификатора.

int * (* (* fp1) (int)) [10 ]; ---> объявление 1

Основываясь на упомянутом выше правиле приоритетов, вы можете легко понять его, разбив объявление как

fp1 * (int) * [10] * int

и прочитав его прямо из слева направо на английском языке как "fp1 - указатель на функцию, принимающую int и возвращающую указатель на массив [10] указателей на int". Обратите внимание, что объявление разбито таким образом только для того, чтобы помочь понять его вручную. Компилятору НЕ нужно разбирать его таким образом.

Аналогично,

int * (* (* [5]) ()) (); --------> объявление 2

прерывается как

[5] * () * () * int

Итак, оно объявляет «массив [5] указателей типов на функцию (), которая возвращает указатель на функцию (), которая, в свою очередь, возвращает указатель на int ".

4
ответ дан 1 December 2019 в 17:29
поделиться

Хотя на него уже был дан ответ, но вы также можете прочитать эту статью:

http://unixwiz.net/techtips/reading-cdecl.html

3
ответ дан 1 December 2019 в 17:29
поделиться

По часовой стрелке / спираль:

* http://c-faq.com/decl/spiral.anderson.html
3
ответ дан 1 December 2019 в 17:29
поделиться

Я давно изучил следующий метод:

Начать с идентификатора типа (или внутренней круглой скобки) и двигаться по спирали, беря сначала элемент справа

В случае, если of

 int * (* (*fp1) (int) ) [10];

Вы можете сказать:

  • fp1 - это (ничего справа, поэтому переместите влево)
  • указатель на (переместите из внутренней скобки
  • функцию, принимающую int как agument (1-я справа )
  • и возвращает указатель на (выход из круглых скобок)
  • массив из 10 элементов типа
  • указатель на (ничего не осталось справа)
  • int

Результат:

fp1 - указатель на функцию, принимающую int и возвращающую указатель на массив из 10 указателей на int

Рисование фактической спирали (по крайней мере, в вашем уме) очень помогает.

7
ответ дан 1 December 2019 в 17:29
поделиться

Начните с крайнего левого идентификатора и продолжайте двигаться дальше, помня, что при отсутствии явной группировки [] и () связываются перед * , например:

    *a[]                 -- is an array of pointer
  (*a)[]                 -- is a pointer to an array
    *f()                 -- is a function returning pointer
  (*f)()                 -- is a pointer to a function

Таким образом, мы читаем int * (* (* fp1) (int)) [10] как:

         fp1                     -- fp1
        *fp1                     -- is a pointer
       (*fp1)(int)               -- to a function
                                      taking an int parameter
      *(*fp1)(int)               -- returning a pointer
     (*(*fp1)(int))[10]          -- to a 10-element array
    *(*(*fp1)(int))[10]          -- of pointer 
int *(*(*fp1)(int))[10]          -- to int

Объявление int * (* (* [5]) ()) () представляет собой небольшую проблему из-за отсутствия идентификатора; вы обычно видите это в объявлениях функций, где параметр имеет этот тип:

void foo(int *(*(*[5])())(), double);

Это тот же принцип, что и безымянный параметр int в объявлении fp1 . Массив дает нам подсказку, вы также можете найти крайнюю левую внутреннюю группу круглых скобок.

                         -- unnamed
         [5]             -- is a 5-element array ([] binds before *)
        *[5]             -- of pointers
       (*[5])()          -- to functions
      *(*[5])()          -- returning pointers
     (*(*[5])())()       -- to functions
    *(*(*[5])())()       -- returning pointers
int *(*(*[5])())()       -- to int
3
ответ дан 1 December 2019 в 17:29
поделиться
Другие вопросы по тегам:

Похожие вопросы: