оператор стрелки (->) в заголовке функции

50

Я нашел такой код:

template <typename T, typename T1> auto compose(T a, T1 b) -> decltype(a + b) {
   return a+b;
}

Я подумал со всеми подробностями, которые были новы для меня, но один. Скажите, пожалуйста, где я могу прочитать, что означает оператор стрелки (->) в заголовке функции? Я предполагаю чисто логически, что оператор -> определяет тип, который будет получен с помощью auto, но я хочу получить это прямо, но не могу найти информацию.

  • 2
    Это часть конечного синтаксиса возвращаемого типа. См. Stackoverflow.com/a/4113390/962089
  • 1
    Это не оператор, а часть синтаксиса.
Показать ещё 1 комментарий
Теги:
c++11
auto
decltype

2 ответа

75
Лучший ответ

В С++ 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 выводятся в один и тот же тип. Синтаксис -> остается полезным для публичных функций (объявленных в заголовке), если вы хотите скрыть тело в исходном файле. Скорее всего, это невозможно сделать с помощью шаблонов, но есть некоторые конкретные типы (обычно полученные через метапрограммирование шаблонов), которые трудно записать иначе.

  • 0
    очень хороший, аккуратный и информативный ответ @Jan Hudec. Пальцы вверх. Что-то изменилось в C++14 как я использую auto для return типа в такой функции без необходимости -> decltype(a + b) часть. Это уже избыточно или есть другие случаи, когда его еще нужно использовать? или это расширение для конкретного компилятора?
  • 1
    @Shadi, C ++ 14 включает N3638 , что позволяет удерживать возвращаемый тип, объявленный как auto , без обозначения -> , если функция полностью определена перед использованием и все операторы return выводят один и тот же тип. Нотация -> все еще полезна, если вы хотите использовать дедукцию для публичной функции, скрывая тело в исходном файле.
11

В простом английском языке он говорит, что возвращаемый тип является выведенным типом суммы a и b.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню