Ответ 1
В С++ 11 есть два синтаксиса для объявления функции:
идентификатор возвращаемого типа (
аргумент-объявления... )
и
auto
идентификатор (
аргумент-объявления... )
->
return_type
Они эквивалентны. Теперь, когда они эквивалентны, почему вы когда-либо хотите использовать последнее? Итак, С++ 11 представил эту классную decltype
вещь, которая позволяет описать тип выражения. Таким образом, вы можете получить тип возврата из типов аргументов. Итак, вы пытаетесь:
template <typename T1, typename T2>
decltype(a + b) compose(T1 a, T2 b);
и компилятор скажет вам, что он не знает, что a
и b
находятся в аргументе decltype
. Это потому, что они объявляются только в списке аргументов.
Вы можете легко решить проблему, используя declval
и параметры шаблона, которые уже объявлены. Как:
template <typename T1, typename T2>
decltype(std::declval<T1>() + std::declval<T2>())
compose(T1 a, T2 b);
за исключением того, что теперь он становится действительно многословным. Поэтому был предложен и реализован синтаксис альтернативного объявления, и теперь вы можете написать
template <typename T1, typename T2>
auto compose(T1 a, T2 b) -> decltype(a + b);
и он менее подробный, и правила определения области обзора не нуждаются в изменении.
Обновление С++ 14: С++ 14 также позволяет просто
auto
идентификатор (
аргумент-объявления... )
пока функция полностью определена перед использованием, и все операторы return
выводятся в один и тот же тип. Синтаксис ->
остается полезным для публичных функций (объявленных в заголовке), если вы хотите скрыть тело в исходном файле. Скорее всего, это невозможно сделать с помощью шаблонов, но есть некоторые конкретные типы (обычно полученные через метапрограммирование шаблонов), которые трудно записать иначе.