Являются несколько условных операторов в этой ситуации хорошей идеей?

Я просто видел этот блок кода на статье Wikipedia об условных операторах:

Vehicle new_vehicle = arg == 'B' ? bus      :
                      arg == 'A' ? airplane :
                      arg == 'T' ? train    :
                      arg == 'C' ? car      :
                      arg == 'H' ? horse    :
                      feet;

Я изменил код немного, но идея является тем же. Вы нашли бы это использование условного оператора приемлемым? Это намного более кратко, чем if-else создайте, и использование переключателя определенно открыло бы совершенно новый набор возможностей для ошибок (падение-throughs кто-либо?). Кроме того, if-elses и switch не может использоваться в качестве R-значений, таким образом, необходимо было бы создать переменную сначала, инициализировать ее и затем присвоиться по мере необходимости.

Я для одного действительно как это, но я задаюсь вопросом, какие другие думают.

Но форматирование важно.

Править: Мне все еще нравится это. Но я понимаю тех, кто говорит" switch оператор был сделан для этого". Хорошо, возможно, так. Но что, если условия являются вызовами функции тот возврат bool? Или миллион других вещей Вы не можете включить.

Вы, переключают любителей, действительно пытающихся убедить меня что огромное if-else цепочка лучше? Да, программисты, которые не знают, как использовать условный оператор, не поймут это. Они должны изучить, как использовать его. Это не тайно.

17
задан Eddie 17 December 2009 в 20:33
поделиться

21 ответ

Я использовал этот тип конструкции много раз. Пока он правильно отформатирован (то есть не все в одной строке, что делает его нечитаемым), я не вижу в этом проблемы.

33
ответ дан 30 November 2019 в 09:56
поделиться

На мой взгляд, то, что вы сделали, приемлемо из-за простоты примера. Если вы будете делать больше вещей с каждым кейсом, этот тип конструкции может быстро испортиться. По этой причине я бы предпочел переключатель или даже вложенные if then elses (если случаев не так много), отформатированные следующим образом:

  if (A) {
      //Do A stuff
  }
  else if (B) {
      //Do B stuff
  }
  else if (C) {
      //Do C stuff
  }
  else {
      //Do default stuff
  }

Речь идет о читабельности кода, которая обеспечивает удобство сопровождения кода. Я никогда не был большим поклонником условного оператора, потому что мне не нравится видеть несколько выражений в одной строке. При пошаговом выполнении кода в отладчике может быть трудно следовать условным операторам. Чем проще код, тем легче сосредоточиться на том, что он делает.

1
ответ дан 30 November 2019 в 09:56
поделиться

Я думаю, что это полезно для того, кто его кодирует, но будет трудно понять для редактора,

«ДЕРЖАТЬ ЭТО ПРОСТО, БАДДИ»

1
ответ дан 30 November 2019 в 09:56
поделиться

Просто для сравнения, в C ++ 0x вы можете иметь выражение без использования условного оператора или автономной функции:

Vehicle new_vehicle = [&]() -> Vehicle {
    if (arg == 'B') return bus;
    if (arg == 'A') return airplane;
    if (arg == 'T') return train;
    if (arg == 'C') return car;
    if (arg == 'H') return horse;
    return feet;
}();

На самом деле не лучше.

1
ответ дан 30 November 2019 в 09:56
поделиться

Как насчет:

enum Vehicle { bus = 'B', airplane = 'A', train, car = 'C', horse = 'H', feet = 'F' };
...
new_vehicle = arg;

:-), кстати.

1
ответ дан 30 November 2019 в 09:56
поделиться

Purely practical:

Plus: The ternary sequence is more flexible, and can be used to avoid the limitations of switch, you could use other operators (e.g. <=, >=) or any other tests, including e.g. string comparisons.

x = IsEven(arg) ?  0 : 
    (arg < 0)   ? -1 : 1; // or whatever

Also, if the switch is a performance bottleneck and you have uneven probabilities, you can force the likeliest tests being done first (due to the not evaluated guarantee for the path not chosen).

So-So Unlike a switch statement, order is important (unless you stick to ==). That can be an advantage, but being otherwise similar to switch that might be misleading when the maintainer is unfamiliar with the concept or in a hurry.

Many developers may shy away because they aren't sure about the details (which terms will be evaluated, is the rpecedence of the operators ok?) - However, if your developer pool won't grasp a well-presented example, you might have problems that can't be solved by banning ternary operators.

Minus It isn't as common as switch, thus the optimizer might not treat it the same. Optimizers are know to select the best fit implementation for a switch (table, binary search, comparison sequence, or any combination of this). Optimizers can't reaarange wevaluaiton order, and are less likely to support a table lookup here.

Requires good formatting to be easily recognizable (lining up the '?' and ':') - Sucks when you use tabs.

Aesthetics

I like it for its precision and succinctness, close to mathematical notations. However, that might as well be used against it. It's probably an eyebrow raiser at code reviews, because it is less common and more brittle.

1
ответ дан 30 November 2019 в 09:56
поделиться

Некоторые люди уже упоминали о возможности использования std :: map или другого типа ассоциативного массива для выполнения работы. Пока вы делаете это только в одном месте (или нескольких местах), вы можете подумать об использовании вместо этого обычного массива или вектора:

Vehicle vehicles[CHAR_MAX];

// Initialization    
std::fill_n(vehicles, CHAR_MAX, feet);
vehicles['A'] = airplane;
vehicles['B'] = bus;
vehicles['C'] = car;
vehicles['H'] = horse;
vehicles['T'] = train;

// Use
Vehicle new_vehicle = vehicles[arg];

В зависимости от того, какие таблицы вам нужны / используют (которые хранят тот же тип object) и размер содержащихся в нем объектов (в данном случае Vehicle), это может быть вполне разумной альтернативой std :: map . Если ты' при повторном создании большого количества таблиц или каждый объект действительно большой, std :: map становится более разумной альтернативой.

Когда вы используете std :: map (или unordered_map и т. Д.) Вы используете больше кода, чтобы сэкономить на хранилище данных. Это делает обратное - но пока Vehicle имеет небольшой размер (скажем, 4 байта), одна таблица, подобная приведенной выше, обычно будет занимать примерно полкилобайта. Трудно угадать точно , насколько большим будет код для std :: map для конкретного компилятора, но кажется вероятным, что он обычно будет больше полкилобайта. , поэтому, если вы создаете только одну такую ​​таблицу, std :: map может быть чистым убытком.

Конечно, если вы знаете, что имеете дело только с буквами в качестве входных данных, вы может немного уменьшить размер таблицы:

1
ответ дан 30 November 2019 в 09:56
поделиться

Прочтите ] Раздел C ++ статьи Википедии немного внимательнее. В нем явным образом перечислены некоторые ситуации, когда использование оператора ?: является единственным вариантом и не может быть заменено переключателем if / else или .

С другой стороны, я бы не стал его использовать только потому, что он выглядит красивее.

2
ответ дан 30 November 2019 в 09:56
поделиться
Vehicle new_vehicle = getVehicleByType(arg);

Vehicle getVehicleByType(char arg){
  if (arg == 'B') return bus;
  if (arg == 'A') return airplane;
  if (arg == 'C') return car;
  if (arg == 'T') return train;
  if (arg == 'H') return horse;
  return feet;
}

Мне это больше нравится. Вложенное условие умно, но я думаю, что оно почти столь же кратко и менее вероятно, чтобы запутать будущего читателя. Извините, если синтаксис отключен, в настоящее время я не использую много C.

EDIT: Исправлено упущение типа возвращаемого значения, отмеченное в комментариях. спасибо!

РЕДАКТИРОВАТЬ: Кстати, я не в ужасе от вашей версии. Я не воскликнул WTF или OMG, когда увидел это. Я просто немного больше предпочитаю свой :)

5
ответ дан 30 November 2019 в 09:56
поделиться

Версия с условным оператором чиста, проста и сразу же очевидна для любого, кто знает C или C ++, что происходит. Другое его достоинство состоит в том, что он возвращает значение немедленно, что означает, что его можно поместить в инициализацию (как в этом примере).

Оператор switch был бы более неуклюжим. Это потребует объявления переменной и ее инициализации, что обычно является плохой идеей, если этого можно избежать. Потребовалось бы больше набора текста и было бы больше мест для вкрапления ошибок. Это было бы не так ясно, поскольку нужно было бы посмотреть на каждый случай, чтобы увидеть, что он говорит что-то вроде new_vehicle = foo; break; .

Если вы собираетесь выполнять этот поиск только здесь, то иметь условную версию прямо здесь хорошо, поскольку она сразу показывает, что происходит. Если это'

8
ответ дан 30 November 2019 в 09:56
поделиться

There's a lot of whitespace around the character constants that makes it a bit hard to read. I'd parenthesize the comparisons: (and maybe move the last value in line.)

Vehicle new_vehicle = (arg == 'B') ? bus      :
                      (arg == 'A') ? airplane :
                      (arg == 'T') ? train    :
                      (arg == 'C') ? car      :
                      (arg == 'H') ? horse    :
                                     feet;

Now it looks great.

11
ответ дан 30 November 2019 в 09:56
поделиться

Меня это особо не волнует.

На самом деле он ничего не дает и не делает ничего более понятного. , и это довольно нестандартное использование оператора.

Кажется, главное преимущество в том, что он несколько умен. Я избегаю умных, если для этого нет достаточно веских (внешних) причин.

3
ответ дан 30 November 2019 в 09:56
поделиться

Я никогда раньше не видел ничего подобного. Несмотря на то, что он продуман и хорошо отформатирован, это кажется прекрасной возможностью использовать словарь / хеш-таблицу (при условии, что Vehicle является перечислением, что неясно).

1
ответ дан 30 November 2019 в 09:56
поделиться

Многие из нас привыкли к Iif-функциям в различных инструментах отчетности или к If-функции в Excel, где нам в основном нужно использовать менее понятный Iif (arg = "B"; "Bus "; Iif (arg =" A "; Airplane;" Feet ")). Мне нравится твой образец по сравнению с ним :) Я бы лично использовал if-elses, но у меня не было бы проблем с вашим образцом.

0
ответ дан 30 November 2019 в 09:56
поделиться

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

2
ответ дан 30 November 2019 в 09:56
поделиться

Чисто стилистический выбор. Для небольших наборов данных, подобных тем, которые вы здесь представляете, то, пока ваша команда программистов не увлечена подобными вещами, все будет хорошо в моей книге.

5
ответ дан 30 November 2019 в 09:56
поделиться

Переключатель более понятен и, возможно, намного эффективнее. Если бы я увидел такой код при проверке кода, я бы забеспокоился. Кроме того, это «условный оператор» - это экземпляр (хотя в настоящее время единственный в C и C ++) тернарного оператора.

5
ответ дан 30 November 2019 в 09:56
поделиться

Мне нравится. Она похожа на лестницу «если-иначе-если», только более лаконична.

11
ответ дан 30 November 2019 в 09:56
поделиться

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

Для замены конструкции if else или switch требуется, чтобы фрагмент кода

"new_vehicle =  "

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

12
ответ дан 30 November 2019 в 09:56
поделиться

Это отличный пример использования условного оператора. Я все время использую его таким образом в C ++, Java и Perl.

14
ответ дан 30 November 2019 в 09:56
поделиться

Я бы использовал переключатель, потому что он был разработан именно для этого. Да, существует риск появления ошибок, но этот вложенный условный блок имеет гораздо более высокий риск быть неправильно понятым другими программистами.

31
ответ дан 30 November 2019 в 09:56
поделиться
Другие вопросы по тегам:

Похожие вопросы: