Обычные функции не включают тип возвращаемого значения в свою подпись.
( примечание : я переписал этот ответ, и приведенные ниже комментарии не относятся к этой ревизии - подробности см. В истории изменений).
Введение
Однако вопрос о функциях и объявлениях функций в Стандарте сложен. Есть два слоя, которые необходимо учитывать:
Так называемое объявление функции может объявлять объект функции или объект шаблона. Если объект функции объявлен, то вы должны либо иметь явную специализацию шаблона функции (с указанием всех аргументов), либо объявление обычной функции. Если объект шаблона объявлен, то вы объявляете шаблон первичной функции или явную специализацию, в которой некоторые аргументы не указаны. (Это очень похоже на отношение «объявления объекта» и объектов или ссылок: первое может объявлять либо объект, либо ссылку. Поэтому объявление объекта не обязательно может объявлять объект!).
Стандарт определяет сигнатуру функции для включения следующего в 1.3.10
:
Типы ее параметров и, если функция является членом класса, cv-квалификаторы (если таковые имеются) для самой функции и класса, в котором объявлена функция-член. Подпись специализации шаблона функции включает типы аргументов шаблона. (14.5.5.1)
В этом определении отсутствует возвращаемый тип, который является частью сигнатуры специализации шаблона функции (т.е. объявления функции, которая объявляет функцию, которая является специализацией шаблона), как указано 14.5.5.1
(исправлены последние рабочие документы C ++ 0x, в которых уже упоминался тип возврата в 1.3.10
):
Подпись специализации шаблона функции состоит из подписи шаблона функции и фактических аргументов шаблона (явно указанных или выведенных).
Сигнатура шаблона функции состоит из сигнатуры его функции, типа возвращаемого значения и списка параметров шаблона.
Итак, что же конкретно содержит подпись?
Итак, когда мы спрашиваем о сигнатуре функции , мы должны дать два ответа:
- Для функций, которые являются специализациями шаблонов функций, подпись включает тип возвращаемого значения.
- Для функций, которые не являются специализациями, тип возвращаемого значения не является частью сигнатуры.
Однако обратите внимание, что тип возвращаемого значения в любом случае составляет значительную часть типа функции. То есть следующее недопустимо:
void f();
int (*pf)() = &f; // different types!
Когда недопустима перегрузка, если отличается только тип возвращаемого значения?
Основные компиляторы в настоящее время отклоняют следующий код:
int f();
double f(); // invalid
Но примите следующий код:
template<typename T> int f();
template<typename T> double f(); // invalid?
Однако стандарт запрещает объявление функции, которая отличается только типом возвращаемого значения (при определении, когда перегрузка допустима, а когда нет). Однако он точно не определяет, что означает «отличается только типом возврата».
Стандартные ссылки на абзацы:
- Когда может быть перегружено объявление функции:
13.1
- Что такое объявление функции:
7/2
и 7/5
- Что такое подпись шаблона функции / специализации:
14.5.5.1
Для справки, вот что говорит самый последний черновик C ++ 0x n3000 о «подписи» в 1.3.11
, что гораздо более полно в охвате различных типов сущностей:
имя и список типов параметров (8.3.5) функции, а также класс или пространство имен, членом которого она является. Если функция или шаблон функции является членом класса, его сигнатура дополнительно включает в себя cv-квалификаторы (если есть) и ref-квалификатор (если есть) для самой функции или самого шаблона функции. Сигнатура шаблона функции дополнительно включает тип возвращаемого значения и список параметров шаблона. Сигнатура специализации шаблона функции включает в себя сигнатуру шаблона, специализацией которого она является, и аргументы шаблона (явно ли они указаны или выведены). [Примечание: подписи используются в качестве основы для искажения имени и связывания. - конец примечания]