代码之家  ›  专栏  ›  技术社区  ›  whacko__Cracko

每个if-else构造都可以被等价的条件表达式替换吗?

  •  7
  • whacko__Cracko  · 技术社区  · 16 年前

    (我不太需要这个答案,我只是好奇。)

    是否可以使用条件运算符将每个if-else构造替换为等效的条件表达式 ?: ?

    8 回复  |  直到 16 年前
        1
  •  11
  •   Ether    16 年前

    是否可以使用条件运算符将每个if-else构造替换为等效的条件表达式?

    if/else的“body”包含语句,不可能将每条语句都转换为表达式 ,例如try、while、break语句以及声明。然而,许多“陈述”实际上是伪装的表达:

    ++i;
    blah = 42;
    some_method(a,b,c);
    

    那么,让我们把问题反过来,因为听起来你真的想知道if/else语句与三元条件表达式的等价程度: 每个条件表达式都能被等价的if/else语句替换吗? 几乎所有的,是的。一个常见的例子是返回语句:

    return cond ? t : f;
    // becomes:
    if (cond) return t;
    else return f;
    

    还有其他表达方式:

    n = (cond ? t : f);
    // becomes:
    if (cond) n = t;
    else n = f;
    

    它开始指向条件表达式无法轻松替换的位置: . 由于只能初始化对象一次,因此必须将使用条件的初始化分解为使用显式临时变量:

    T obj (cond ? t : f);
    // becomes:
    SomeType temp;
    if (cond) temp = t;
    else temp = f;
    T obj (temp);
    

    请注意,这要繁琐得多,如果SomeType不能默认构造和分配,则需要依赖于类型的东西。

        2
  •  4
  •   Ether    16 年前

    从表面上看,不是。条件运算符是一个表达式(即它有一个值),而if/else是一个语句(因此没有值)。它们在语言语法中满足不同的“需求”。

    // Original code:
    if (condition) {
      // block 1
    }
    else {
      // block 2
    }
    
    // conditional expression replacement:
    
    bool if_block() {
      // block 1
      return true;
    }
    
    bool else_block() {
      // block 2
      return true;
    }
    
    // Here's the conditional expression.  bool value discarded:
    condition ? if_block() : else_block();
    

    然而,话虽如此,我不确定这是否只是一种好奇。。。

        3
  •  2
  •   DrPizza    16 年前

    不,当然不是。原因已经提到,还有更多!

    #include <cstdlib>
    #include <iostream>
    
    int main()
    {
        if(int i = std::rand() % 2)
        {
            std::cout << i << " is odd" << std::endl;
        }
        else
        {
            std::cout << i << " is even" << std::endl;
        }
    }
    

    查看声明的位置。这不是一种常用的技术,但它可以用于COM等情况,其中每个调用都返回HRESULT,成功时(几乎总是)为零(s_OK),失败时为非零,因此您可以编写如下内容:

    if(HRESULT hr = myInterface->myMethod())
    {
        _com_raise_error(hr);
    }
    

        4
  •  1
  •   Michael Krelin - hacker    16 年前
    if( cond )
        break;
    else
        a=b;
    

    不能总是被 ?: ?: . break return throw

        5
  •  1
  •   sdcvvc    16 年前

    原则上,是的:

    if (A) B; else C
    

    try {
      A ? throw TrueResult() : throw FalseResult();
      // or: throw A ? TrueResult() : FalseResult();
    } catch (TrueResult) {
      B;
    } catch (FalseResult) {
      C;
    }
    

    与使用程序(更自然)相比,这允许 break , continue , return 等等。它需要对 A TrueResult / FalseResult 但是如果你使用这些异常只是为了模拟 if ,这不会是问题。

        6
  •  1
  •   Ether    16 年前

    使用条件运算符将生成表达式,并且条件运算符的两个潜在结果必须“兼容”(可转换为相同类型)。

    if - else 构造甚至不需要“返回”任何类型,更不用说从两个分支返回相同的类型了。

        7
  •  1
  •   Ether    16 年前

    条件运算符希望在 ?

    (condition) ? return x : return y;
    

    而if-else版本则相当标准:

    if(condition) return x;
    else return y;
    

    现在,也就是说,你能接受任何一个程序并编写一个功能类似的程序,而不使用if-else吗?当然可以。但这并不意味着这是个好主意

        8
  •  0
  •   sambowry    16 年前

    海湾合作委员会 statement expression if ?: 表达:

    if (<expression>)
      <statement1>
    else
      <statement2>

    void ?: 必须具有相同的类型,并且没有 编译器可以打印的强制转换 warning: statement with no effect .

    (<expression>)? (void)({<statement1>}) : (void)({<statement2>});