В примере Страуструпа, что означает двоеточие в «возврате 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. Я понятия не имею, что это может быть. Это не лейбл или троичный оператор.

Это похоже на условный троичный оператор без первого члена (и без ?), но в этом случае я не понимаю, как он мог бы работать без условия.

Piockñec
источник
6
Это ошибка компиляции с моей стороны (gcc и clang). Плюс ко всем этим строкам нужны точки с запятой, но все равно ошибка.
Крус Жан
216
Примечание модератора: Пожалуйста, очень тщательно подумайте, прежде чем голосовать, чтобы закрыть этот вопрос как "опечатку". Да, проблема в опечатке, но это не опечатка, которую сделал аскер. Скорее, он найден в опубликованной книге. Это означает, что этот вопрос и его ответы вполне могут быть полезны для других в будущем, что является сильным противоиндикатором для закрытия его как опечатки. (ОБНОВЛЕНИЕ: эта тема в настоящее время обсуждается на Мета ; пожалуйста, не стесняйтесь взвешивать там.)
Коди Грей
3
Возможно, лучшим ответом будет: попробуйте скомпилировать код; если он не компилируется, это хороший признак того, что это опечатка.
jrw32982 поддерживает Монику
Я могу вспомнить ряд примеров, которые не в моей голове компилируются (или даже вызывают внутреннюю ошибку компилятора) на одном компиляторе, но принимаются без проблем на другом
J. Antonio Perez
1
@ Джон Я только что попробовал несколько выражений сгиба с MSVC, но они не компилировались. Так ясно, что вся глава, которую я только что прочитал, должна быть опечаткой? ;) Компиляторы C ++ не могут все время компилировать корректный код C ++, это происходит из-за нелепо сложного языка.
Voo

Ответы:

205

Это опечатка в книге. Посмотрите на исправления для 2-й и 3-й печатных версий языка программирования C ++ . Пример должен быть как ниже:

auto z3 =[y]() { return (y) ? 1 : 2; }
SM
источник
11
Почему (y)и не просто y?
Маленький помощник
7
@LittleHelper Возможно, это лучшая практика или что-то в этом роде, я всегда вижу, что так написано. Может быть, чтобы избежать путаницы с более сложными сравнениями ...
Программы
28
Лично я часто использую (cond) ? a : bдля ясности - это помогает мне избежать неправильного прочтения, например, утверждение, foo = x > y ? a : bкак foo = x ...при просмотре кода.
user1686
8
@LittleHelper Это действительно не нужно там. Однако в функционально-подобном макросе рекомендуется ставить круглые скобки вокруг аргументов, в которых они используются, потому что в противном случае расширение аргументов может привести к неожиданному поведению. Рассмотрим функциональный макрос для удвоения значения «foo (x) x * 2», где вы называете его с помощью «foo (2 + 3)». Результат будет 2+ (3 * 2), потому что аргумент расширяется как есть и правила приоритета вступают во владение. Если ваш макрос "foo (x) (x) * 2"), вы получите правильно (2 + 3) * 2. Может быть, у Страуструпа есть привычка использовать этот стиль повсюду для безопасности кодирования.
Грэм
2
@ Грэм очень маловероятно. По сути, Страуструп не пишет макросы функций (лучше встроенные функции C ++). Гораздо более вероятно, что у троичного оператора есть несколько сложные правила приоритета, поэтому хорошо обычно разъяснять приоритет с помощью паренов.
Мартин Боннер поддерживает Монику
19

Выглядит как простая опечатка. Вероятно, должно быть:

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

Обратите внимание, что, поскольку лямбда не принимает никаких параметров, паренсы являются необязательными. Вы можете использовать это вместо этого, если вы предпочитаете:

auto z3 =[y] { return y ? 1 : 2; }
Джерри Гроб
источник
11

return 1 : 2; это синтаксическая ошибка, это не правильный код

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

Реми Лебо
источник