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


128

Я натрапив на такий код:

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

Є одне, чого я не можу зрозуміти:

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


2
Це частина синтаксису зворотного типу. Дивіться stackoverflow.com/a/4113390/962089
chris

2
Це не оператор, а частина синтаксису.
texasbruce

1
У відповідь "де я можу прочитати?", Специфікація C ++ є найбільш авторитетною. Не маючи коштів або бажання витратити $$, останній робочий проект часто є досить близьким і без витрат. Ці характеристики дуже високомовні, тому не вистачає ознайомлення з читанням специфікацій ISO, спробуйте cplusplus.com або cppreference.com чи інші подібні сайти, які не є авторитетними, але зазвичай дуже точними. Примітка: тип останнього повернення може бути опущений, починаючи з C ++ 14.
Les

Відповіді:


205

У C ++ 11 є два синтаксиси для оголошення функції:

     аргументи-декларації ідентифікатора типу return ( ... )

і

    auto ідентифікатор ( аргументу-декларації ... ) -> return_type

Вони рівноцінні. Тепер, коли вони рівноцінні, чому ви взагалі хочете використовувати останні? Ну, C ++ 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);

і вона менш докладна, і правила розміщення не потрібно змінювати.


Оновлення на C ++ 14: C ++ 14 також дозволяє лише

    auto ідентифікатор ( аргументу-декларації ... )

до тих пір, поки функція буде повністю визначена перед використанням, і всі returnоператори виводяться до одного типу. ->Синтаксис залишається корисним для громадських функцій (оголошених в заголовку) , якщо ви хочете , щоб приховати тіло в вихідному файлі. Дещо очевидно, що неможливо зробити з шаблонами, але є деякі конкретні типи (як правило, отримані за допомогою метапрограмування шаблонів), які важко написати інакше.


2
дуже хороша, акуратна та інформативна відповідь @Jan Hudec. Піднімається вгору. Чи щось змінилося, C++14як я використовую autoдля returnтипу в такій функції, без потреби в -> decltype(a + b)частині. Чи є це зайвим на сьогодні чи є в інших випадках, коли його все ж слід використовувати? чи це розширення для компілятора?
Шаді

1
@Shadi, C ++ 14 включає N3638 , що дозволяє виводити тип повернення, оголошений як auto, без ->позначень, до тих пір, поки функція буде повністю визначена перед використанням і всі returnвиводи виводиться на один і той же тип. ->Позначення ще корисно , якщо ви хочете використовувати відрахування для публічної функції, приховуючи тіло в вихідному файлі.
Ян Худек

23

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

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.