【问题标题】:Conditional operator always replaceable by if/else?条件运算符总是可以被 if/else 替换?
【发布时间】:2010-12-17 22:00:35
【问题描述】:

到目前为止,我一直认为条件运算符 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 语句替换。

我对这个结论是否正确?

【问题讨论】:

  • 我删除了 [c] 标签,因为您的问题在极端案例示例中使用了引用
  • 你的意思是a = x1a = x2,对吧?
  • @SiegeX:谢谢,我对 c 不是很熟悉,我想它也会与 c 有关。
  • 您将赋值作为三元 a?b:c 运算符的一部分包含在内......有点像红鲱鱼。在许多情况下 if/else 和三元是不可互换的。 if/else 版本是语句,三元运算符是表达式,因此,例如,您不能将 if/else 版本用作函数调用的参数。
  • @Jefromi:是的,我要脸红了。

标签: c++ conditional-operator


【解决方案1】:

你是对的。条件运算符是一个表达式,而if-else 是一个语句。可以用语句的地方可以用表达式,反之则不行。

这是一个很好的反例,当你遇到有人坚持认为你不应该、永远、永远、永远不要使用条件表达式时,这是一个很好的反例,因为if-else 是“简单”而条件是“太复杂”。

当 C++ 获得 lambda 表达式时,您可以使用带有 if-else 的 lambda 来代替条件。

【讨论】:

  • +1。将三元运算符视为“替代品”会有所帮助。
  • -1 除了第一个陈述“你是对的”之外,这个答案是正确的。根据您要保留的内容,条件运算符可以或不能用其他东西替换,但由于它取决于,断言它不能是错误。具体示例每次都优于断言,因此我包含了用 ifswitch 重写 OP 示例的具体示例。
  • 提问者的断言是“条件运算符并不总是可以被 if/else 语句替换。”我认为这是正确的。 “视情况而定”和“不总是”几乎是同义词。
  • 不,它们几乎不是同义词。对于保留文字源代码的选择,无法替换的陈述是平凡的,但空洞的。选择不同的约束会改变结论:给定任何示例,对于给定的要保留内容的选择,人们会发现 :? 不能用 if 替换,这是要保留的内容的不同选择(例如,如我的示例中所示) 让您进行替换。这就像说你可以花 1 美元买任何你想要的东西,因为你事先决定不想要任何花费更多的东西。从这个意义上说是对的,但毫无意义。
【解决方案2】:

嗯,显然有很多地方不能放置 if。例如:

func( x ? 0 : 1 );

没有办法用 if 语句来写。这是一个骗局,好几次,不是我怪你没有找到它,因为我找不到。

【讨论】:

  • +1:大部分是真的……当然你可以使用if (x) func(0); else func(1);
  • @Roddy 叹息。这取决于您所说的“替换”是什么意思。
  • 将其更改为const Foo y = func( x ? 0 : 1 ),@Roddy 的投诉就会消失。 (虽然你可以说!x 会比条件更好,所以不同的值可能会改进示例。)
  • @Roddy, Jonathan:当然,如果func 有六个其他参数,并且您要在 if-else 中复制它们,那么使用条件运算符肯定会更清楚。
【解决方案3】:

不完全是。您始终可以用指针(可重新安装)替换参考(不可重新安装)。所以这是一个上下文问题。

例如你可以写

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);

干杯,

【讨论】:

  • @Nim:我想知道是否还包括表格查找变体等,但为了简洁明了的效果决定反对。 :-)
  • 正确。唯一在默认之前忘记中断的事情:。
【解决方案4】:

你会遇到更多的问题

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


// stringstream* and fstream* -- incompatible!
ostream *o = x ? &myfiles : &mystrings;

【讨论】:

  • 你知道,演员阵容还不错。
【解决方案5】:

你是对的。

在 C++ 中存在条件赋值情况,无法使用 if-else 语句,因为该语言明确区分初始化和赋值。

此外,三元运算符可以产生一个左值,即可以分配另一个值的值。

此外,某些编译器在某些情况下可能会为三元与条件 if-then 生成不同的代码。例如,如果使用三元运算符,GCC 会执行更好的代码优化。

另见?: ternary operator in C++

【讨论】:

    【解决方案6】:

    您不能直接使用它,但您始终可以通过将条件转换为作为表达式评估的内容来绕过该限制...

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

    当然,这对整数来说可能有点过分了。

    【讨论】:

      【解决方案7】:

      这取决于您对可替换的定义。例如,在单个函数调用中,我无法将以下条件运算符替换为 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);
      }
      

      【讨论】:

        【解决方案8】:

        根据kodify.net,我们不能用条件运算符替换每个if/else 语句。这样做有两个要求:ifelse 块中必须有一个表达式。

        【讨论】:

          猜你喜欢
          • 2013-01-19
          • 1970-01-01
          • 2013-01-19
          • 2019-10-20
          • 2023-03-03
          • 1970-01-01
          • 1970-01-01
          • 2011-06-04
          • 1970-01-01
          相关资源
          最近更新 更多