троичный оператор с ++ - PullRequest
8 голосов
/ 15 июля 2010

Таким образом, я столкнулся с чем-то интересным, что я не осознал в тернарном операторе (по крайней мере в Visual C ++ 98-2010). Как указано в http://msdn.microsoft.com/en-us/library/e4213hs1(VS.71).aspx, если и выражение, и условное выражение являются l-значениями, результатом является l-значение.

Конечно, обычно в c / c ++ вы пишете что-то вроде:

int value = (x == 1) ? 1 : 0;

и никогда даже не заботится о вовлеченности r-значения / l-значения, и в этом случае ни 1, ни 0 не могут быть преобразованы в l-значения.

Однако возьмите что-то вроде:

int value = (x == 1) ? y : z;

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

Но к чему приводит способность написать следующее

(x == 1 ? y : z) = 99;

Что присваивает 99 к y, если x == 1 или 99 к z, если x! = 1

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

Конечно, это работает только в том случае, если и выражение, и условное выражение являются l-значениями, например,

(x == 1 ? 0 : z) = 99;

не скомпилируется, потому что 0 - это r-значение, как радостно указал компилятор.

И это работает, только если включить скобку

x == 1 ? y : z = 99;

- это нечто совершенно иное, которое присваивает 99 к z, только если (x! = 1), и прекрасная часть состоит в том, что обе стороны все еще являются l-значениями, поэтому существует серьезная пробел того, что делают (x == 1 ? y : z = 99) = 100 он назначает 100 для y или z в зависимости от истинности x == 1, топая при назначении z = 99, если x == 1 является ложным)

Итак, это подводит меня к моим вопросам:

A) Является ли это частью действующего стандарта c ++ (кажется, что так и будет), а не просто вещью Microsoft - я посмотрел, но пока не смог найти эту информацию.

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

C) Нужно ли выходить чаще?

Ответы [ 3 ]

10 голосов
/ 15 июля 2010

A) Да, это часть стандарта.

B) Это не очень широко реализовано, хотя может быть здесь, на SO.Есть причина, по которой за нее проголосовали # 1 скрытая особенность C ++: Скрытые возможности C ++? .

C) Без комментариев.:)

Лично я рекомендую избегать использования этой функции.Это намного менее интуитивно понятно, чем использование if / else операторов, и, очевидно, не все об этом знают.

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

3 голосов
/ 15 июля 2010

A. Да.§ [expr.cond] / 4:

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

(Обратите внимание, что это не верно для C. Явно написано в стандарте C99, сноска 93, «Условное выражение не дает lvalue.»)

Б. Я не думаю, что он широко используется, так как использование довольно неясное.Чаще встречается

if (x == 1)
  y = 99;
else
  z = 99;
2 голосов
/ 15 июля 2010

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

Помните, что C ++ Стандарты кодирования *1003* Херба Саттера и Андрея Александреску , правило 6: «Правильность, простота и ясность на первом месте».

...