Почему возвращаемый тип перед именем функции?
Новый стандарт C++11 добавляет новый синтаксис объявления функции с завершающим типом возврата:
// Usual declaration
int foo();
// New declaration
auto foo() -> int;
Преимущество этого синтаксиса состоит в том, что он позволяет выводить тип возвращаемого значения, например:
template<class T, class U>
auto bar(T t, U u) -> decltype(t + u);
Но тогда зачем возвращаемый тип ставится перед именем функции? Я полагаю, что одним из ответов будет то, что в то время не было необходимости в таких выводах. Если да, есть ли причина для гипотетического нового языка программирования не использовать конечный тип возврата по умолчанию?
2 ответа
Как всегда, K&R - "плохие парни" здесь. Они разработали этот синтаксис функции для C, и C++ в основном унаследовал его как есть.
Дикое предположение здесь: в C объявление должно указывать на использование, т. Е. Как получить значение из чего-либо. Это отражено в:
- простые значения:
int i;
,int
доступ к письмуi
- указатели:
int *p;
,int
доступ к письму*p
- массивы:
int a[n];
,int
доступ к письмуa[n]
- функции:
int f();
,int
доступ к письмуf()
Таким образом, весь выбор зависел от случая "простых значений". И, как уже заметил @JerryCoffin, причина, по которой мы получили type name
вместо name : type
вероятно, похоронен в древней истории языков программирования. Я думаю, что K & R взял type name
так как легче сделать акцент на использовании и при этом иметь указатели и т. д. быть типами.
Если бы они выбрали name : type
они бы либо отключили использование от объявлений: p : int*
иначе бы указатели перестали быть типами, а стали бы украшением имени: *p : int
,
От себя лично: представьте, если бы они выбрали последний вариант, а C++ унаследовал это - это просто не сработало бы, так как C++ делает упор на использование типов вместо использования. Это также причина, почему int* p
называется "C++ way" и int *p
быть "C путь".
Если да, есть ли причина для гипотетического нового языка программирования не использовать конечный тип возврата по умолчанию?
Есть ли причина не использовать вычет по умолчанию?;) См., Например, Python или Haskell (или любой функциональный язык в этом отношении, IIRC) - явно не указаны возвращаемые типы. Существует также движение, чтобы добавить эту функцию в C++, так что когда-нибудь в будущем вы можете увидеть просто auto f(auto x){ return x + 42; }
или даже []f(x){ return x + 42; }
,
C++ основан на C, который был основан на B, который был основан на BCPL, который был основан на CPL.
Я подозреваю, что если бы вы проследили всю историю, вы, вероятно, оказались бы в Фортране, который использовал такие объявления, как integer x
(в отличие, например, от Pascal, который использовал объявления вроде: var x : integer;
).
Аналогично, для функции Паскаль использовал что-то вроде function f(<args>) : integer;
В этих обстоятельствах, вероятно, можно с уверенностью предположить, что (по крайней мере, в этом конкретном отношении) синтаксис Паскаля, вероятно, будет лучше соответствовать выводу типа.