На прикладі Струструпа, що означає двокрапка у "поверненні 1: 2"?


163

Я не розумію одного конкретного вживання двокрапки.

Я знайшов це в книзі Мова програмування на C ++ Б'ярна Струструпа, 4-е видання, розділ 11.4.4 "Дзвінки та повернення", стор. 297:

void g(double y)
{
  [&]{ f(y); }                                               // return type is void
  auto z1 = [=](int x){ return x+y; }                        // return type is double
  auto z2 = [=,y]{ if (y) return 1; else return 2; }         // error: body too complicated
                                                             // for return type deduction
  auto z3 =[y]() { return 1 : 2; }                           // return type is int
  auto z4 = [=,y]()−>int { if (y) return 1; else return 2; } // OK: explicit return type
}

Заплутана двокрапка відображається у рядку 7 у виписці return 1 : 2. Я поняття не маю, що це може бути. Це не етикетка чи потрійний оператор.

Здається, що це умовний термінальний оператор без першого члена (і без ?), але в такому випадку я не розумію, як це могло б працювати без умови.


6
Це помилка компіляції на моєму кінці (gcc та clang). Плюс до всіх цих рядків потрібні крапки з комою, але все ж помилка.
Крус Жан

216
Модератор Примітка: Будь ласка, подумайте дуже ретельно перед голосуванням, щоб закрити це як "друкарське" питання. Так, проблема - це помилка друку, але це не помилка, яку зробив запитувач. Скоріше, це знайдено у виданій книзі. Це означає, що це питання та його відповіді можуть бути корисними іншим у майбутньому, що є сильним контрпоказником для закриття його як друкарського помилки. (ОНОВЛЕННЯ: Ця тема зараз обговорюється на Meta ; будь ласка,
Коді Грей

3
Можливо, найкращою відповіддю буде: Спробуйте скласти код; якщо він не компілюється, це хороший показник того, що це помилка друку.
jrw32982 підтримує Моніку

Я можу придумати декілька прикладів у верхній частині моєї голови, які не можуть скласти (або навіть викликати внутрішню помилку компілятора) на одному компіляторі, але приймаються без проблем на іншому
Дж. Антоніо Перес,

1
@John Я просто спробував декілька складних виразів з MSVC, і вони не компілювали. Так чітко, що вся глава, яку я щойно прочитав, повинна бути помилковою? ;) Компілятори C ++ не в змозі збирати дійсний код C ++ весь час, оскільки мова є абсурдно складною.
Voo

Відповіді:


205

Це друкарня в книзі. Подивіться на Еррата для другої та третьої друк мови програмування C ++ . Приклад повинен бути таким:

auto z3 =[y]() { return (y) ? 1 : 2; }

11
Чому (y)і не просто y?
Маленький помічник

7
@LittleHelper Можливо, це найкраща практика чи щось таке, я завжди бачу, що це написано так. Можливо, щоб уникнути плутанини із складнішими порівняннями ...
Програми

28
Особисто я часто використовую (cond) ? a : bдля наочності - це допомагає мені уникнути неправильного читання, наприклад, висловлювання, foo = x > y ? a : bяк foo = x ...під час перегляду коду.
користувач1686

8
@LittleHelper Це насправді не потрібно. Однак у макрокоманді, подібному до функцій, найкраще застосовувати дужки навколо аргументів там, де вони використовуються, оскільки в іншому випадку розширення аргументів може спричинити несподівану поведінку. Розглянемо функціональний макрос, щоб подвоїти значення "foo (x) x * 2", де ви називаєте це "foo (2 + 3)". Результат буде 2+ (3 * 2), оскільки аргумент розширюється як є, а правила пріоритету переймають. Якщо ваш макрос "foo (x) (x) * 2", ви правильно отримаєте (2 + 3) * 2. Можливо, Stroustrup має звичку використовувати цей стиль скрізь для безпеки кодування.
Грем

2
@Graham Дуже малоймовірно. Stroustrup по суті не записує макроси функцій (краще вбудовані функції C ++). Набагато ймовірніше, що потрійний оператор має дещо складні правила пріоритетності, тому добре звично уточнити пріоритет з паронами.
Мартін Боннер підтримує Моніку

19

Мені це здається простим друком. Напевно, має бути:

auto z3 =[y]() { return y ? 1 : 2; }

Зауважте, що оскільки лямбда не приймає жодних параметрів, паролі необов’язкові. Ви можете використовувати це замість цього, якщо хочете:

auto z3 =[y] { return y ? 1 : 2; }

11

return 1 : 2; це синтаксична помилка, це недійсний код.

Правильне твердження було б більше схожим return (y) ? 1 : 2;натомість.

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