Условный оператор всегда заменяется на if / else? - PullRequest
4 голосов
/ 18 декабря 2010

До сих пор я думал, что условный оператор int a = b == 2 ? x1 : x2; всегда можно заменить оператором if / else.

int a;
if (b == 2)
  a = x1;
else
  a = x2;

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

int& a;
if (b == 2)
  a = x1;
else
  a = x2;

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

Прав ли я с этим выводом?

Ответы [ 7 ]

11 голосов
/ 18 декабря 2010

Вы правы.Условный оператор - это выражение , тогда как if-else - это выражение .Выражение можно использовать там, где можно использовать выражение, но обратное неверно.

Это хороший контрпример, который можно увидеть, когда вы сталкиваетесь с кем-то, кто настаивает на том, что вы никогда, никогда, никогда, никогда не должны использоватьусловные выражения, поскольку if-else является «простым», а условные выражения «слишком сложными».

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

2 голосов
/ 18 декабря 2010

У вас будет больше проблем, чем

// works
ostream *o;
if(x)
  o = &myfiles;
else
  o = &mystrings;


// stringstream* and fstream* -- incompatible!
ostream *o = x ? &myfiles : &mystrings;
2 голосов
/ 18 декабря 2010

Не совсем.Вы всегда можете заменить ссылку (не переставляемую) указателем (переставляемую).Так что это вопрос контекста.

Например, вы можете написать

int* pa;
if( b == 2 )
    pa = &x1;
else
    pa = &x2;
int& a = *pa;

Нет проблем, как кто-то однажды заметил Терминатору.тьфу, что этот"эффект,

int* pa;
switch( b == 2 )
{
case true:
    pa = &x1;  break;
default:
    pa = &x2;
}
int& a = *pa;

Но это более понятно с условным оператором в этом случае.: -)

int& a = (b == 2? x1 : x2);

Приветствия и hth.,

2 голосов
/ 18 декабря 2010

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

func( x ? 0 : 1 );

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

1 голос
/ 18 декабря 2010

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

int& initValue(int b, int& x1, int& x2){
    if (b==2)
        return x1;
    return x2;
}

...

int& a = initValue(b, x1, x2);

Конечно, это может быть излишним для целых.

1 голос
/ 18 декабря 2010

Вы правы.

В C ++ существуют ситуации условного присваивания, когда использование оператора if-else невозможно, поскольку этот язык явно различает инициализацию и присваивание.

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

Кроме того, некоторые компиляторы в некоторых случаях могут генерировать другой код для троичного по сравнению с условным if-then.GCC, например, выполняет лучшую оптимизацию кода, если используется троичный оператор.

См. Также ?: троичный оператор в C ++ .

0 голосов
/ 18 декабря 2010

Это зависит от вашего определения заменяемого.Например, в рамках одного вызова функции я не могу заменить следующий условный оператор на if-else.

int n1 = 10;
int n2 = 20;
const int& i = x > 0 ? n1 : n2;

Однако, добавив еще одну функцию, я фактически заменил условный оператор наif-else.

const int& get_i(double x)
{
  if(x > 0)
    return n1;
  else
    return n2;
}

int main()
{
  const int& i = get_i(x);
}
...