К троичному или не к троичному? [закрытый]

Я помещаю превосходный ответ JLBorges на аналогичный вопрос дословно из cplusplus.com, так как это наиболее краткое объяснение, которое я прочитал по этому вопросу.

] В шаблоне, который мы пишем, есть два типа имен, которые можно использовать - зависимые имена и не зависимые имена. Зависимое имя - это имя, которое зависит от параметра шаблона; неизменяемое имя имеет то же значение, независимо от параметров шаблона.

Например:

template< typename T > void foo( T& x, std::string str, int count )
{
    // these names are looked up during the second phase
    // when foo is instantiated and the type T is known
    x.size(); // dependant name (non-type)
    T::instance_count ; // dependant name (non-type)
    typename T::iterator i ; // dependant name (type)

    // during the first phase, 
    // T::instance_count is treated as a non-type (this is the default)
    // the typename keyword specifies that T::iterator is to be treated as a type.

    // these names are looked up during the first phase
    std::string::size_type s ; // non-dependant name (type)
    std::string::npos ; // non-dependant name (non-type)
    str.empty() ; // non-dependant name (non-type)
    count ; // non-dependant name (non-type)
}

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

На первом этапе анализатор должен знать, является ли зависимое имя именем типа или имени не-типа. По умолчанию зависимым именем считается имя не-типа.

Использовать ключевое слово typename только в объявлениях шаблонов и определениях, приведенных ниже.

blockquote>

у вас есть квалифицированное имя, которое относится к типу и зависит от параметра шаблона.

180
задан 7 revs, 6 users 57% 4 September 2016 в 19:54
поделиться

50 ответов

Используйте его для простые выражения [только 116]:

int a = (b > 10) ? c : d;

не объединяют в цепочку или вложенное множество тернарные операторы как он трудно для чтения и сбивающий с толку:

int a = b > 10 ? c < 20 ? 50 : 80 : e == 2 ? 4 : 8;

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

int a = (b > 10) ? some_value                 
                 : another_value;
236
ответ дан 2 revs, 2 users 87% 23 November 2019 в 06:11
поделиться

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

единственное время я думаю, что тернарные операторы делают код тяжелее для понимания, когда у Вас есть больше чем 3 или 4 в одной строке. Большинство людей не помнит, что они - основанный на праве приоритет и когда у Вас есть стек их, он делает чтение кода кошмаром.

2
ответ дан Alex 23 November 2019 в 06:11
поделиться

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

2
ответ дан Svet 23 November 2019 в 06:11
поделиться

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

Как второстепенный вопрос, я мог бы также отметить, что его самое существование является на самом деле чем-то вроде anomoly вследствие того, что в C, сравнительное испытание является оператором. В Значке if конструкция (как большая часть Значка) является на самом деле выражением. Таким образом, можно сделать вещи как:

x[if y > 5 then 5 else y] := "Y" 

..., который я нахожу намного более читаемыми, чем троичный оператор сравнения. :-)

была дискуссия недавно о возможности добавления ?: оператор к Значку, но несколько человек правильно указали, что не было абсолютно никакой потребности из-за пути if работы.

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

2
ответ дан staticsan 23 November 2019 в 06:11
поделиться

Объединенный в цепочку все хорошо с - вложенный, не так.

я склонен использовать их больше в C просто b/c, они, если оператор, который имеет значение, таким образом, это сокращает ненужное повторение или переменные:

x = (y < 100) ? "dog" :
    (y < 150) ? "cat" :
    (y < 300) ? "bar" : "baz";

, а не

     if (y < 100) { x = "dog"; } 
else if (y < 150) { x = "cat"; }
else if (y < 300) { x = "bar"; } 
else              { x = "baz"; }

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

, Когда я работаю в рубине, с другой стороны, я, более вероятно, буду использовать if...else...end, потому что это - выражение также.

x =   if (y < 100) then "dog"
    elif (y < 150) then "cat"
    elif (y < 300) then "bar"
    else                "baz"
    end

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

41
ответ дан rampion 23 November 2019 в 06:11
поделиться

Оператор Ternary ?: является просто функциональным эквивалентом процедурного if конструкция. Таким образом, пока Вы не используете вложенный ?: выражения, аргументы в пользу функционального представления любой операции применяются здесь. Но вложенные троичные операции могут привести к коду, который совершенно сбивает с толку (осуществление для читателя: попытайтесь писать синтаксический анализатор, который обработает вложенные троичные условные выражения, и Вы будете ценить их сложность).

, Но существует много ситуаций, где консервативное использование ?: оператор может привести к коду, который является на самом деле легче для чтения, чем иначе. Например:

int compareTo(Object object) {
    if((isLessThan(object) && reverseOrder) || (isGreaterThan(object) && !reverseOrder)) {
       return 1;
    if((isLessThan(object) && !reverseOrder) || (isGreaterThan(object) && reverseOrder)) {
       return -1;
    else
      return 0;              
}

Теперь сравнивают это с этим:

int compareTo(Object object) {
    if(isLessThan(object))
        return reverseOrder ? 1 : -1;         
    else(isGreaterThan(object))
        return reverseOrder ? -1 : 1;
    else        
       return 0;              
}

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

39
ответ дан 2 revs, 2 users 96% 23 November 2019 в 06:11
поделиться

Это - вопрос стиля, действительно; подсознательные правила, за которыми я склонен следовать:

  • Только оценивают 1 выражение - так foo = (bar > baz) ? true : false, но НЕ foo = (bar > baz && lotto && someArray.Contains(someValue)) ? true : false
  • , Если я использую его для логики дисплея, например, <%= (foo) ? "Yes" : "No" %>
  • , Only действительно использует его для присвоения; никогда не теките, логика (поэтому никогда (foo) ? FooIsTrue(foo) : FooIsALie(foo)) логика Потока в троичном является самостоятельно ложью, проигнорируйте ту последнюю точку.

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

24
ответ дан 2 revs 23 November 2019 в 06:11
поделиться

Как столько вопросов о мнении, ответ неизбежно: это зависит

Для чего-то как:

return x ? "Yes" : "No";

я думаю, что это очень более кратко (и более быстрый, чтобы я проанализировал), чем:

if (x) {
    return "Yes";
} else {
    return "No";
}

Теперь, если Ваше условное выражение сложно, то троичная операция не является хорошим выбором. Что-то как:

x && y && z >= 10 && s.Length == 0 || !foo

не хороший кандидат на тернарный оператор.

Как в стороне, если Вы - программист C, GCC на самом деле имеет расширение , который позволяет Вам исключать если - истинная часть троичного, как это:

/* 'y' is a char * */
const char *x = y ? : "Not set";

, Который установит x на y, принятие y не NULL. Хороший материал.

18
ответ дан Sean Bright 23 November 2019 в 06:11
поделиться

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

В других случаях, это походит на ясность уменьшений тернарного оператора.

12
ответ дан John Mulder 23 November 2019 в 06:11
поделиться

Мерой цикломатическая сложность , использование if операторы или тернарный оператор эквивалентны. Таким образом той мерой, ответ никакой , сложность была бы точно тем же как прежде.

другими мерами, такими как удобочитаемость, пригодность для обслуживания и DRY (Don't-Repeat-Yourself), любой выбор может оказаться лучше, чем другой.

11
ответ дан Greg Hewgill 23 November 2019 в 06:11
поделиться

Я использую его довольно часто в местах, где я вынужден работать в конструкторе - например, новая.NET 3.5 LINQ к конструкциям XML - для определения значений по умолчанию, когда дополнительный параметр является пустым.

Изобретенный пример:

var e = new XElement("Something",
    param == null ? new XElement("Value", "Default")
                  : new XElement("Value", param.ToString())
);

или (благодарит астерит)

var e = new XElement("Something",
    new XElement("Value",
        param == null ? "Default"
                      : param.ToString()
    )
);

, Неважно, ли Вы используете тернарный оператор или нет, удостоверяясь, Ваш код читаем, важная вещь. Любая конструкция может быть сделана нечитабельной.

10
ответ дан 3 revs 23 November 2019 в 06:11
поделиться

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

Это всегда озадачивает меня, как некоторые люди думают, что тернарный оператор является "скрытой" функцией или является несколько таинственным. Это - одна из первых вещей, которые я изучил, когда я начинаю программировать в C, и я не думаю, что это уменьшает удобочитаемость вообще. Это - естественная часть языка.

9
ответ дан 2 revs 23 November 2019 в 06:11
поделиться

Я соглашаюсь с jmulder: это не должно использоваться вместо if, но это имеет свое место для выражения возврата или в выражении:

echo "Result: " + n + " meter" + (n != 1 ? "s" : "");
return a == null ? "null" : a;

Первый - просто пример, лучшая i18n поддержка множественного числа должна использоваться!

7
ответ дан 2 revs 23 November 2019 в 06:11
поделиться

Мне нравится особый случай Groovy тернарного оператора, названного оператором Elvis:?:

expr ?: default

Этот код оценивает к expr, если это не является пустым, и по умолчанию, если это. Технически это не действительно тернарный оператор, но это определенно связано с ним и экономит много времени.

2
ответ дан Steve Losh 23 November 2019 в 06:11
поделиться

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

6
ответ дан Bill the Lizard 23 November 2019 в 06:11
поделиться

Я думаю, что тернарный оператор должен использоваться при необходимости. Это - очевидно, очень субъективный выбор, но я нахожу, что простое выражение (особенно как выражение возврата) намного более ясно, чем полный тест. Пример в C/C++:

return (a>0)?a:0;

По сравнению с:

if(a>0) return a;
else return 0;

у Вас также есть случай, где решение между тернарным оператором и созданием функции. Например, в Python:

l = [ i if i > 0 else 0 for i in lst ]

альтернатива:

def cap(value):
    if value > 0:
        return value
    return 0
l = [ cap(i) for i in lst ]

необходимо достаточно, чтобы в Python (как пример), такая идиома регулярно была видна:

l = [ ((i>0 and [i]) or [0])[0] for i in lst ]

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

5
ответ дан PierreBdR 23 November 2019 в 06:11
поделиться

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

5
ответ дан JimDaniel 23 November 2019 в 06:11
поделиться

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

isLeapYear =
    ((yyyy % 400) == 0)
    ? 1
    : ((yyyy % 100) == 0)
        ? 0
        : ((yyyy % 4) == 0)
            ? 1
            : 0;

, где, явно, серия операторов "if" была бы лучше (хотя это еще лучше, чем макро-версия я однажды видел).

я не возражаю против него для мелочей как:

reportedAge = (isFemale && (Age >= 21)) ? 21 + (Age - 21) / 3 : Age;

или даже немного хитрые вещи как:

printf ("Deleted %d file%s\n", n, (n == 1) ? "" : "s");
5
ответ дан paxdiablo 23 November 2019 в 06:11
поделиться

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

int result = do_something();
if( result != 0 )
{
  debug_printf("Error while doing something, code %x (%s)\n", result,
                result == 7 ? "ERROR_YES" :
                result == 8 ? "ERROR_NO" :
                result == 9 ? "ERROR_FILE_NOT_FOUND" :
                "Unknown");
}
4
ответ дан indiv 23 November 2019 в 06:11
поделиться

Я почти никогда не использую тернарный оператор, потому что каждый раз, когда я ДЕЙСТВИТЕЛЬНО использую его, он всегда заставляет меня думать намного больше, чем я имею к позже, когда я пытаюсь поддержать его.

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

Рассмотрите:

String name = firstName;

if (middleName != null) {
    name += " " + middleName;
}

name += " " + lastName;

Теперь, который является немного подробным, но я нахожу его намного более читаемым, чем:

String name = firstName + (middleName == null ? "" : " " + middleName)
    + " " + lastName;

или:

String name = firstName;
name += (middleName == null ? "" : " " + middleName);
name += " " + lastName;

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

4
ответ дан 2 revs 23 November 2019 в 06:11
поделиться

Ну, синтаксис для него неприятен. Я нахожу функциональную IFS очень полезной, и часто делает код более читаемым.

я предложил бы делать макрос для создания его более читаемым, но я уверен, что кто-то может придумать ужасный пограничный случай (как всегда существует с CPP).

3
ответ дан Marcin 23 November 2019 в 06:11
поделиться

Только, когда:

$var = (простой> тест? simple_result_1: simple_result_2);

KISS.

3
ответ дан Jared Farrish 23 November 2019 в 06:11
поделиться

Я обычно использую в вещах как это:

before:

if(isheader)
    drawtext(x,y,WHITE,string);
else
    drawtext(x,y,BLUE,string);

after:

    drawtext(x,y,isheader==true?WHITE:BLUE,string);
3
ответ дан KPexEA 23 November 2019 в 06:11
поделиться

Поскольку другие указали, что они хороши для коротких простых условий. Мне особенно нравятся они за значения по умолчанию (отчасти как || и или использование в JavaScript и Python), например,

int repCount = pRepCountIn ? *pRepCountIn : defaultRepCount;

, Другое общее использование должно инициализировать ссылку в C++. Так как ссылки должны быть объявлены и инициализированы в том же операторе, который Вы не можете использовать если оператор.

SomeType& ref = pInput ? *pInput : somethingElse;
3
ответ дан maccullt 23 November 2019 в 06:11
поделиться

Я рассматриваю тернарные операторы много как GOTO. У них есть свое место, но они - что-то, что необходимо обычно стараться не делать код легче понять.

2
ответ дан Dan Walker 23 November 2019 в 06:11
поделиться

Я недавно видел изменение на тернарных операторах (хорошо, вид), которые делают стандарт" ()?": вариант, кажется, образец ясности:

var Result = [CaseIfFalse, CaseIfTrue][(boolean expression)]

или, для предоставления более материального примера:

var Name = ['Jane', 'John'][Gender == 'm'];

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

2
ответ дан pilsetnieks 23 November 2019 в 06:11
поделиться

Для простого, если случаи, мне нравится использовать его. На самом деле намного легче читать/кодировать, например, как параметры для функций или подобных вещей. Также для предотвращения новой строки мне нравится сохранять со всеми мой если/еще.

Neseting это было бы большое НЕТ - НЕТ в моей книге.

Так, возобновление, для сингла, если/еще я буду использовать тернарный оператор. Для других случаев постоянный клиент, если/еще, если/еще (или переключатель)

2
ответ дан Rodrigo Gómez 23 November 2019 в 06:11
поделиться

Я люблю их, особенно на безопасных с точки зрения типов языках.

я не вижу как это:

int count = (condition) ? 1 : 0;

немного тяжелее, чем это:

int count;

if (condition)
{
  count = 1;
} 
else
{
  count = 0;
}

редактирование -

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

81
ответ дан Ian P 23 November 2019 в 06:11
поделиться

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

133
ответ дан 2 revs 23 November 2019 в 06:11
поделиться

Нет. Их трудно считать. Если/Еще намного легче читать.

Это - мое мнение. Ваш пробег может варьироваться.

1
ответ дан Genericrich 23 November 2019 в 06:11
поделиться
Другие вопросы по тегам:

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