каково различие между объявлением функции и подписью?

В C или C++, каково различие между объявлением функции и функциональной подписью?

Я знаю что-то вроде объявления функции, но функциональная подпись полностью плохо мне знакома. Какой смысл того, чтобы иметь понятие функциональной подписи? Для чего используются эти два понятия на самом деле?

Спасибо!

38
задан Tim 24 February 2010 в 00:23
поделиться

5 ответов

Объявление функции - это прототип для функции (или он может исходить из определения функции, если компилятор не видел прототипа в этот момент) - он включает тип возврата, имя функции и типы параметров (опционально в C).

Сигнатура функции - это часть объявления функции, которую компилятор использует для разрешения перегрузки. Поскольку несколько функций могут иметь одно и то же имя (т.е. они перегружены), компилятору нужен способ определить, к какой из нескольких возможных функций с определенным именем должен разрешиться вызов функции. Сигнатура - это то, что компилятор учитывает при разрешении перегрузки. В частности, стандарт определяет "сигнатуру" как:

информацию о функции, которая участвует в разрешении перегрузки: типы ее параметров и, если функция является членом класса, cv-квалификаторы (если таковые имеются) самой функции и класса, в котором объявлена функция-член.

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

42
ответ дан 27 November 2019 в 03:48
поделиться

Сигнатура функции не включает тип возвращаемого значения или тип связи функции.

Хорошо, Википедия не согласна со мной по поводу включения типа возвращаемого значения. Однако я знаю, что тип возвращаемого значения не используется компилятором при принятии решения о том, соответствует ли вызов функции сигнатуре. Этот предыдущий вопрос StackOverflow, похоже, согласуется: Является ли тип возвращаемого значения частью сигнатуры функции?

3
ответ дан 27 November 2019 в 03:48
поделиться

Объявление функции - это прототип. Подпись функции указывает тип возвращаемого значения и используемые параметры, составляющие подпись. Рассмотрим это:

int foo(int, int);  /* Function Declaration */


/* Implementation of foo 
** Function signature
*/
int foo(int a, int b){
}

Теперь рассмотрим следующий сценарий: программиста спрашивают, какова сигнатура функции для foo :

  • Он возвращает тип данных int
  • Два параметра также имеют тип данных int , названный a и b соответственно

Прототип функции, с другой стороны, указывает компилятору C / C ++, что нужно ожидайте, и если подпись не соответствует прототипу, компилятор выдаст ошибку в контексте «ошибки объявления функции» или «несоответствия прототипа».

-1
ответ дан 27 November 2019 в 03:48
поделиться

Стандарт определяет два термина: декларация и определение. Определение - это предварительное заявление. Однако стандарты C99 и C ++ 03 имеют немного разные определения.

Из черновика C ++ 0x:

Приложение C

8.3.5 Изменение: в C ++ функция, объявленная с пустым списком параметров, не принимает аргументов . . В C пустой список параметров означает, что количество и тип аргументов функции неизвестны »

Определения

1.3.11 подпись

имя и параметр - type-list (8.3.5) функции, а также класс , концепция, карта концепций или пространство имен , членом которого она является. Если {{ 1}} функция или шаблон функции является членом класса, его подпись дополнительно включает квалификаторы cv (если есть) и квалификатор ссылки ( если есть) в самой функции или шаблоне функции. Подпись ограниченного члена (9.2) включает в себя требования к его шаблону . Подпись { Шаблон функции {1}} дополнительно включает тип возвращаемого значения, список параметров шаблона и требования к шаблону (если есть). Подпись специализация шаблона функции включает подпись шаблона , специализацией которого она является, и его аргументы шаблона (независимо от того, указаны ли явно или де duced). [ Примечание: подписи используются в качестве основы для изменения имен и связывания. — Конец примечание]

6
ответ дан 27 November 2019 в 03:48
поделиться

Также обратите внимание, что const верхнего уровня и volatile на аргументе не являются частью сигнатуры, согласно стандарту. Но некоторые компиляторы понимают это неправильно.

Например,

void f(const int, const char* const);

имеет ту же сигнатуру, что и

void f(int, const char*);
1
ответ дан 27 November 2019 в 03:48
поделиться