Таким образом, я столкнулся с чем-то интересным, которое я не понял о тернарном операторе (по крайней мере, в Visual C++ 98-2010). Как указано в http://msdn.microsoft.com/en-us/library/e4213hs1 (По сравнению с 71) .aspx, если и выражение и условное выражение являются l-значениями, результатом является l-значение.
Конечно, обычно в c/c ++ Вы записали бы что-то как:
int value = (x == 1) ? 1 : 0;
и даже не забота о r-value/l-value involvment, и в этом случае ни 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 - я посмотрел, но и не удался, до сих пор, найти эту информацию.
B) Если это широко понято, и я жил под скалой? Я никогда не видел, что это использовало в любом коде, который я могу вспомнить, и никогда не замечаемый это упомянуло, когда тернарный оператор обсужден.
C) Я должен выходить чаще?
A) Да, это часть стандарта.
B) Это не так широко реализовано, хотя может быть здесь, на SO. Не зря он был признан скрытой функцией №1 C ++: Скрытые возможности C ++? .
C) Без комментариев. :)
Лично я рекомендую воздерживаться от использования этой функции. Это намного менее интуитивно понятно, чем использование операторов if
/ else
, и, очевидно, не все об этом знают.
Вопреки моему собственному предупреждению, я на самом деле однажды попытался использовать это в личном проекте, и меня обгорело из-за того, что я пропустил круглые скобки и потратил 30 минут на поиск ошибки.
A. Да. §[expr.cond]/4:
Если второй и третий операнды являются l-значениями и имеют одинаковый тип, то результат имеет этот тип и является l-значением ....
(Обратите внимание, что это не верно в C. Явно написано в стандарте C99, сноска 93, "Условное выражение не дает l-значения.")
B. Я не думаю, что это широко используется, так как использование довольно неясно. Чаще можно встретить
if (x == 1)
y = 99;
else
z = 99;
Вы никогда не видели, чтобы он использовался, потому что это использование менее интуитивно понятно и читабельно, чем наиболее распространенное. Я никогда не видел, чтобы это использовалось таким образом в производственном коде, и я надеюсь, что никогда не увижу этого.
Вспомните Стандарты кодирования C ++ Херба Саттера и Андрея Александреску , правило 6: «Правильность, простота и ясность на первом месте»